#include "build.h" char *cwd; int mv_if_change(mv_mode m,char *newfile,char *oldfile) { FILE *nfp,*ofp; char buf[MAXDIRLEN+1]; char c,nc,oc; int nr,or; assert( (newfile != NULL) && (oldfile != NULL) && (buf != NULL) ); if ((nfp = fopen(newfile,"r")) == NULL) { sprintf(buf,"%s: read %s",toolname,newfile); perror(buf); if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } return 1; } if ((ofp = fopen(oldfile,"r")) == NULL) { if ((ofp = fopen(oldfile,"w"))==NULL) { sprintf(buf,"%s: write %s",toolname,oldfile); perror(buf); if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } return 1; } while (fread(&c,1,1,nfp) == 1) fwrite(&c,1,1,ofp); if (m == mv_interactive) cout << toolname << ": " << oldfile << " created." << endl; fclose(nfp); fclose(ofp); if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } return 0; } nr = fread(&nc,1,1,nfp); or = fread(&oc,1,1,ofp); while ( (nr == or) && (nr != 0) && (nc == oc)) { nr = fread(&nc,1,1,nfp); or = fread(&oc,1,1,ofp); } fclose(nfp); fclose(ofp); if ((nr == or) && (nr == 0)) { if (m == mv_interactive) cout << toolname << ": " << oldfile << " is up to date." << endl; if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } return 0; } if ((nfp = fopen(newfile,"r")) == NULL) { sprintf(buf,"%s: open %s",toolname,newfile); perror(buf); if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } return 1; } if ((ofp = fopen(oldfile,"w"))==NULL) { sprintf(buf,"%s: open %s",toolname,oldfile); perror(buf); if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } return 1; } while (fread(&c,1,1,nfp) == 1) fwrite(&c,1,1,ofp); if (m == mv_interactive) cout << toolname << ": " << oldfile << " recreated." << endl; if (unlink(newfile)) { sprintf(buf,"%s: warning : rm %s",toolname,newfile); perror(buf); } fclose(nfp); fclose(ofp); return 0; } int dotname(const char *s) { assert( s!= NULL ); if (s[0] == '.') if (s[1] == '.') if (s[2] == '\0') return (1); else return (0); else if (s[1] == '\0') return (1); return (0); } int rm(const char *arg) { int fail = 0; struct stat buf; struct dirent *dp; DIR *dirp; char fullname[MAXDIRLEN+1 + 1]; char *cp; assert( (toolname != NULL) && (arg != NULL) ); if (dotname(arg)) { cerr << toolname << ": cannot remove `.' or `..'\n"; return (1); } if (lstat(arg, &buf)) return (0); /* error */ if ((buf.st_mode&S_IFMT) == S_IFDIR) { if (access(arg, R_OK|W_OK|X_OK) != 0) { cerr << toolname << ": cannot remove " << arg << endl; return (1); } if ((dirp = opendir((char *)arg)) == NULL) { cerr << toolname << ": cannot read " << arg << endl; return (1); } while ((dp = readdir(dirp)) != NULL) { if (dotname(dp->d_name)) continue; sprintf(fullname,"%s/%s",arg,dp->d_name); closedir(dirp); if (rm(fullname)) fail = 1; if ((dirp = opendir((char *)arg)) == NULL) { cerr << toolname << ": cannot read " << arg << endl; return (1); } } closedir(dirp); if (rmdir(arg) < 0) { cerr << toolname << ": cannot remove " << arg << endl; return (1); } return (fail); } if (unlink(arg) < 0) { cerr << toolname << ": cannot remove " << arg << endl; return (1); } return (0); } void abort_with_help() { assert(toolname != NULL); cout << "\n" << toolname << " [ -selftest ] [ -trace ] [ -clean ] [ -propagate ] [ -inter ] [ -compile ] construct-file.sys\n"; cout << toolname << " [ -selftest ] [ -trace ] [ -clean ] [ -propagate ] [ -inter ] [ -compile ] directory\n"; cout << toolname << " -help \n" << endl; exit(0); } int polishpath_aux(char *b,char *n) /* n points to the first / */ { char *f,*s; char buf[MAXDIRLEN+1]; int r; assert( (b != NULL) && (n != NULL) && (buf != NULL) ); if (*n == '\0') return 1; f = n+1; while ( (*f != '\0') && (*f != '/') ) f++; if (*f == '\0') { if ((f-n == 2) && (*(n+1) == '.')) { *n = '\0'; return 1; } else if ((f-n == 3) && (*(n+1) == '.') && (*(n+2) == '.')) return 0; else return 1; } else { if (f == n+1) { strcpy(buf,f); strcpy(n,f); return polishpath_aux(b,n); } if ((f-n == 2) && (*(n+1) == '.')) { strcpy(buf,f); strcpy(n,f); return polishpath_aux(b,n); } else if ((f-n == 3) && (*(n+1) == '.') && (*(n+2) == '.')) { if (n == b) return 0; n--; while ( (*n != '/') && (n != b) ) n--; if (*n == '/') { strcpy(buf,f); strcpy(n,f); return polishpath_aux(b,n); } else return 0; } else return polishpath_aux(b,f); } } void polishpath(char *n) /* n should begin with / */ { char buf[MAXDIRLEN+1]; assert( (n!= NULL) && (buf != NULL) ); strcpy(buf,n); if (polishpath_aux(buf,buf)) strcpy(n,buf); } void basename(char *n) { char buf[MAXDIRLEN+1]; char *p; assert( (n!= NULL) && (buf != NULL) ); if (*n == '\0') { strcpy(n,cwd); return; } p = n + strlen(n)-1; while ( (p!=n) && (*p != '/')) p--; if ( *n == '/' ) { *(p+1) = '\0'; return; } if ( n == p ) { strcpy(n,cwd); return; } else { strcpy(buf,n); sprintf(n,"%s/%s",cwd,buf); return; } } void absolutename(char *n) { char buf[MAXNAMLEN]; char *p; assert( (n!= NULL) && (buf != NULL) ); if (*n == '/') return; derror('i',strlen(n)+strlen(cwd)+2 > MAXDIRLEN, "absolutename(): name buffer overflow."); strcpy(buf,n); sprintf(n,"%s/%s",cwd,buf); return; } void derror(char c,int cond, char *msg) { if (!cond) return; switch (c) { case 'i': cerr << toolname << ": " << version << ": internal error: " << msg << endl; exit(1); case 'd': cerr << toolname << ": " << version << ": debug: " << msg << endl; break; case 'e': cerr << toolname << ": error: " << msg << endl; exit(1); } } char *ppfname(char *env_path,char *env_name,Header *header, int file_count) { char *targetfile = new char[MAXDIRLEN+1]; char * oname; header->fetch_op_name(oname); if (strlen(env_name)+strlen(oname)+10 <= MAXNAMLEN) sprintf(targetfile,"%s/%s-%d-%s.pp",env_path,env_name,file_count,oname); else sprintf(targetfile,"%s/%s-%d.pp",env_path,env_name,file_count); return targetfile; } char *metafname(char *env_path,char *env_name,Header *header, int file_count) { char *targetfile = new char[MAXDIRLEN+1]; char * oname; header->fetch_op_name(oname); if (strlen(env_name)+strlen(oname)+10 <= MAXNAMLEN) sprintf(targetfile,"%s/%s-%d-%s.meta",env_path,env_name,file_count,oname); else sprintf(targetfile,"%s/%s-%d.meta",env_path,env_name,file_count); return targetfile; } char *renfname(char *env_path,char *env_name,Header *header, int file_count) { char *targetfile = new char[MAXDIRLEN+1]; char * oname; header->fetch_op_name(oname); if (strlen(env_name)+strlen(oname)+10 <= MAXNAMLEN) sprintf(targetfile,"%s/%s-%d-%s.ren",env_path,env_name,file_count,oname); else sprintf(targetfile,"%s/%s-%d.ren",env_path,env_name,file_count); return targetfile; } char *cppfname(char *env_path,char *env_name,Header *header, int file_count) { char *targetfile = new char[MAXDIRLEN+1]; char * oname; header->fetch_op_name(oname); if (strlen(env_name)+strlen(oname)+10 <= MAXNAMLEN) sprintf(targetfile,"%s/%s-%d-%s.C",env_path,env_name,file_count,oname); else sprintf(targetfile,"%s/%s-%d.C",env_path,env_name,file_count); return targetfile; } char *tmpfname() { char *r; static i = 1000000; r = new char[MAXDIRLEN+1]; sprintf(r,"%s/%s-%d",tmpdir,toolname,i); i++; return r; }