#include "semcheck.h" 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); } char *tmpfname() { char *r; static i = 1000000; r = new char[42]; sprintf(r,"%s/%s-%d",tmpdir,toolname,i); i++; return r; }