util.c

Go to the documentation of this file.
00001 #include "EXTERN.h"
00002 #include "common.h"
00003 #include "INTERN.h"
00004 #include "util.h"
00005 
00006 /* Rename a file, copying it if necessary. */
00007 
00008 int
00009 move_file(from,to)
00010 char *from, *to;
00011 {
00012     char bakname[512];
00013     Reg1 char *s;
00014     Reg2 int i;
00015     Reg3 int fromfd;
00016 
00017     /* to stdout? */
00018 
00019     if (strEQ(to, "-")) {
00020 #ifdef DEBUGGING
00021         if (debug & 4)
00022             say2("Moving %s to stdout.\n", from);
00023 #endif
00024         fromfd = open(from, 0);
00025         if (fromfd < 0)
00026             fatal2("patch: internal error, can't reopen %s\n", from);
00027         while ((i=read(fromfd, buf, sizeof buf)) > 0)
00028             if (write(1, buf, i) != i)
00029                 fatal1("patch: write failed\n");
00030         Close(fromfd);
00031         return 0;
00032     }
00033 
00034         if (origprae) {
00035                 Strcpy (bakname, origprae);
00036         Strcat(bakname, to);
00037         } else {
00038                 Strcpy(bakname, to);
00039         Strcat(bakname, origext?origext:ORIGEXT);
00040         }
00041     if (stat(to, &filestat) >= 0) {     /* output file exists */
00042         dev_t to_device = filestat.st_dev;
00043         ino_t to_inode  = filestat.st_ino;
00044         char *simplename = bakname;
00045         
00046         for (s=bakname; *s; s++) {
00047             if (*s == '/')
00048                 simplename = s+1;
00049         }
00050         /* find a backup name that is not the same file */
00051         while (stat(bakname, &filestat) >= 0 &&
00052                 to_device == filestat.st_dev && to_inode == filestat.st_ino) {
00053             for (s=simplename; *s && !islower(*s); s++) ;
00054             if (*s)
00055                 *s = toupper(*s);
00056             else
00057                 Strcpy(simplename, simplename+1);
00058         }
00059         while (unlink(bakname) >= 0) ;  /* while() is for benefit of Eunice */
00060 #ifdef DEBUGGING
00061         if (debug & 4)
00062             say3("Moving %s to %s.\n", to, bakname);
00063 #endif
00064         if (link(to, bakname) < 0) {
00065             say3("patch: can't backup %s, output is in %s\n",
00066                 to, from);
00067             return -1;
00068         }
00069         while (unlink(to) >= 0) ;
00070     }
00071 #ifdef DEBUGGING
00072     if (debug & 4)
00073         say3("Moving %s to %s.\n", from, to);
00074 #endif
00075     if (link(from, to) < 0) {           /* different file system? */
00076         Reg4 int tofd;
00077         
00078         tofd = creat(to, 0666);
00079         if (tofd < 0) {
00080             say3("patch: can't create %s, output is in %s.\n",
00081               to, from);
00082             return -1;
00083         }
00084         fromfd = open(from, 0);
00085         if (fromfd < 0)
00086             fatal2("patch: internal error, can't reopen %s\n", from);
00087         while ((i=read(fromfd, buf, sizeof buf)) > 0)
00088             if (write(tofd, buf, i) != i)
00089                 fatal1("patch: write failed\n");
00090         Close(fromfd);
00091         Close(tofd);
00092     }
00093     Unlink(from);
00094     return 0;
00095 }
00096 
00097 /* Copy a file. */
00098 
00099 void
00100 copy_file(from,to)
00101 char *from, *to;
00102 {
00103     Reg3 int tofd;
00104     Reg2 int fromfd;
00105     Reg1 int i;
00106     
00107     tofd = creat(to, 0666);
00108     if (tofd < 0)
00109         fatal2("patch: can't create %s.\n", to);
00110     fromfd = open(from, 0);
00111     if (fromfd < 0)
00112         fatal2("patch: internal error, can't reopen %s\n", from);
00113     while ((i=read(fromfd, buf, sizeof buf)) > 0)
00114         if (write(tofd, buf, i) != i)
00115             fatal2("patch: write (%s) failed\n", to);
00116     Close(fromfd);
00117     Close(tofd);
00118 }
00119 
00120 /* Allocate a unique area for a string. */
00121 
00122 char *
00123 savestr(s)
00124 Reg1 char *s;
00125 {
00126     Reg3 char *rv;
00127     Reg2 char *t;
00128 
00129     if (!s)
00130         s = "Oops";
00131     t = s;
00132     while (*t++);
00133     rv = (char *)malloc((MEM) (t - s));
00134     if (rv == Nullch) {
00135         if (using_plan_a)
00136             out_of_mem = TRUE;
00137         else
00138             fatal1("patch: out of memory (savestr)\n");
00139     }
00140     else {
00141         t = rv;
00142         while (*t++ = *s++);
00143     }
00144     return rv;
00145 }
00146 
00147 #if defined(lint) && defined(CANVARARG)
00148 
00149 /*VARARGS ARGSUSED*/
00150 say(pat) char *pat; { ; }
00151 /*VARARGS ARGSUSED*/
00152 fatal(pat) char *pat; { ; }
00153 /*VARARGS ARGSUSED*/
00154 ask(pat) char *pat; { ; }
00155 
00156 #else
00157 
00158 /* Vanilla terminal output (buffered). */
00159 
00160 void
00161 say(pat,arg1,arg2,arg3)
00162 char *pat;
00163 long arg1,arg2,arg3;
00164 {
00165     fprintf(stderr, pat, arg1, arg2, arg3);
00166     Fflush(stderr);
00167 }
00168 
00169 /* Terminal output, pun intended. */
00170 
00171 void                            /* very void */
00172 fatal(pat,arg1,arg2,arg3)
00173 char *pat;
00174 long arg1,arg2,arg3;
00175 {
00176     say(pat, arg1, arg2, arg3);
00177     my_exit(1);
00178 }
00179 
00180 /* Get a response from the user, somehow or other. */
00181 
00182 void
00183 ask(pat,arg1,arg2,arg3)
00184 char *pat;
00185 long arg1,arg2,arg3;
00186 {
00187     int ttyfd;
00188     int r;
00189     bool tty2 = isatty(2);
00190 
00191     Sprintf(buf, pat, arg1, arg2, arg3);
00192     Fflush(stderr);
00193     write(2, buf, strlen(buf));
00194     if (tty2) {                         /* might be redirected to a file */
00195         r = read(2, buf, sizeof buf);
00196     }
00197     else if (isatty(1)) {               /* this may be new file output */
00198         Fflush(stdout);
00199         write(1, buf, strlen(buf));
00200         r = read(1, buf, sizeof buf);
00201     }
00202     else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
00203                                         /* might be deleted or unwriteable */
00204         write(ttyfd, buf, strlen(buf));
00205         r = read(ttyfd, buf, sizeof buf);
00206         Close(ttyfd);
00207     }
00208     else if (isatty(0)) {               /* this is probably patch input */
00209         Fflush(stdin);
00210         write(0, buf, strlen(buf));
00211         r = read(0, buf, sizeof buf);
00212     }
00213     else {                              /* no terminal at all--default it */
00214         buf[0] = '\n';
00215         r = 1;
00216     }
00217     if (r <= 0)
00218         buf[0] = 0;
00219     else
00220         buf[r] = '\0';
00221     if (!tty2)
00222         say1(buf);
00223 }
00224 #endif /* lint */
00225 
00226 /* How to handle certain events when not in a critical region. */
00227 
00228 void
00229 set_signals(reset)
00230 int reset;
00231 {
00232 #ifndef lint
00233 #ifdef VOIDSIG
00234     static void (*hupval)(),(*intval)();
00235 #else
00236     static int (*hupval)(),(*intval)();
00237 #endif
00238 
00239     if (!reset) {
00240         hupval = signal(SIGHUP, SIG_IGN);
00241         if (hupval != SIG_IGN)
00242 #ifdef VOIDSIG
00243             hupval = my_exit;
00244 #else
00245             hupval = (int(*)())my_exit;
00246 #endif
00247         intval = signal(SIGINT, SIG_IGN);
00248         if (intval != SIG_IGN)
00249 #ifdef VOIDSIG
00250             intval = my_exit;
00251 #else
00252             intval = (int(*)())my_exit;
00253 #endif
00254     }
00255     Signal(SIGHUP, hupval);
00256     Signal(SIGINT, intval);
00257 #endif
00258 }
00259 
00260 /* How to handle certain events when in a critical region. */
00261 
00262 void
00263 ignore_signals()
00264 {
00265 #ifndef lint
00266     Signal(SIGHUP, SIG_IGN);
00267     Signal(SIGINT, SIG_IGN);
00268 #endif
00269 }
00270 
00271 /* Make sure we'll have the directories to create a file. */
00272 
00273 void
00274 makedirs(filename,striplast)
00275 Reg1 char *filename;
00276 bool striplast;
00277 {
00278     char tmpbuf[256];
00279     Reg2 char *s = tmpbuf;
00280     char *dirv[20];
00281     Reg3 int i;
00282     Reg4 int dirvp = 0;
00283 
00284     while (*filename) {
00285         if (*filename == '/') {
00286             filename++;
00287             dirv[dirvp++] = s;
00288             *s++ = '\0';
00289         }
00290         else {
00291             *s++ = *filename++;
00292         }
00293     }
00294     *s = '\0';
00295     dirv[dirvp] = s;
00296     if (striplast)
00297         dirvp--;
00298     if (dirvp < 0)
00299         return;
00300     strcpy(buf, "mkdir");
00301     s = buf;
00302     for (i=0; i<=dirvp; i++) {
00303         while (*s) s++;
00304         *s++ = ' ';
00305         strcpy(s, tmpbuf);
00306         *dirv[i] = '/';
00307     }
00308     system(buf);
00309 }
00310 
00311 /* Make filenames more reasonable. */
00312 
00313 char *
00314 fetchname(at,strip_leading,assume_exists)
00315 char *at;
00316 int strip_leading;
00317 int assume_exists;
00318 {
00319     char *s;
00320     char *name;
00321     Reg1 char *t;
00322     char tmpbuf[200];
00323 
00324     if (!at)
00325         return Nullch;
00326     s = savestr(at);
00327     for (t=s; isspace(*t); t++) ;
00328     name = t;
00329 #ifdef DEBUGGING
00330     if (debug & 128)
00331         say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
00332 #endif
00333     if (strnEQ(name, "/dev/null", 9))   /* so files can be created by diffing */
00334         return Nullch;                  /*   against /dev/null. */
00335     for (; *t && !isspace(*t); t++)
00336         if (*t == '/')
00337             if (--strip_leading >= 0)
00338                 name = t+1;
00339     *t = '\0';
00340     if (name != s && *s != '/') {
00341         name[-1] = '\0';
00342         if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
00343             name[-1] = '/';
00344             name=s;
00345         }
00346     }
00347     name = savestr(name);
00348     Sprintf(tmpbuf, "RCS/%s", name);
00349     free(s);
00350     if (stat(name, &filestat) < 0 && !assume_exists) {
00351         Strcat(tmpbuf, RCSSUFFIX);
00352         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
00353             Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
00354             if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
00355                 free(name);
00356                 name = Nullch;
00357             }
00358         }
00359     }
00360     return name;
00361 }

Generated on Fri Apr 14 22:56:45 2006 for minix by  doxygen 1.4.6