home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / PATCHSRC / UTIL.C < prev    next >
C/C++ Source or Header  |  1991-03-28  |  8KB  |  370 lines

  1. #include "EXTERN.h"
  2. #include "common.h"
  3. #include "INTERN.h"
  4. #include "util.h"
  5.  
  6. /* Rename a file, copying it if necessary. */
  7.  
  8. int
  9. move_file(from,to)
  10. char *from, *to;
  11. {
  12.     char bakname[512];
  13.     Reg1 char *s;
  14.     Reg2 int i;
  15.     Reg3 int fromfd;
  16.  
  17. #ifdef GNUDOS
  18.     rename(from,to);
  19. #else
  20.  
  21.     /* to stdout? */
  22.  
  23.     if (strEQ(to, "-")) {
  24. #ifdef DEBUGGING
  25.     if (debug & 4)
  26.         say2("Moving %s to stdout.\n", from);
  27. #endif
  28.     fromfd = open(from, 0);
  29.     if (fromfd < 0)
  30.         fatal2("patch: internal error, can't reopen %s\n", from);
  31.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  32.         if (write(1, buf, i) != 1)
  33.         fatal1("patch: write failed\n");
  34.     Close(fromfd);
  35.     return 0;
  36.     }
  37.  
  38.     if (origprae) {
  39.         Strcpy (bakname, origprae);
  40.         Strcat(bakname, to);
  41.     } else {
  42.            Strcpy(bakname, to);
  43.         Strcat(bakname, origext?origext:ORIGEXT);
  44.     }
  45.     if (stat(to, &filestat) >= 0) {    /* output file exists */
  46.     dev_t to_device = filestat.st_dev;
  47.     ino_t to_inode  = filestat.st_ino;
  48.     char *simplename = bakname;
  49.     
  50.     for (s=bakname; *s; s++) {
  51.         if (*s == '/')
  52.         simplename = s+1;
  53.     }
  54.     /* find a backup name that is not the same file */
  55.     while (stat(bakname, &filestat) >= 0 &&
  56.         to_device == filestat.st_dev && to_inode == filestat.st_ino) {
  57.         for (s=simplename; *s && !islower(*s); s++) ;
  58.         if (*s)
  59.         *s = toupper(*s);
  60.         else
  61.         Strcpy(simplename, simplename+1);
  62.     }
  63.     while (unlink(bakname) >= 0) ;    /* while() is for benefit of Eunice */
  64. #ifdef DEBUGGING
  65.     if (debug & 4)
  66.         say3("Moving %s to %s.\n", to, bakname);
  67. #endif
  68.     if (link(to, bakname) < 0) {
  69.         say3("patch: can't backup %s, output is in %s\n",
  70.         to, from);
  71.         return -1;
  72.     }
  73.     while (unlink(to) >= 0) ;
  74.     }
  75. #ifdef DEBUGGING
  76.     if (debug & 4)
  77.     say3("Moving %s to %s.\n", from, to);
  78. #endif
  79.     if (link(from, to) < 0) {        /* different file system? */
  80.     Reg4 int tofd;
  81.     
  82.     tofd = creat(to, 0666);
  83.     if (tofd < 0) {
  84.         say3("patch: can't create %s, output is in %s.\n",
  85.           to, from);
  86.         return -1;
  87.     }
  88.     fromfd = open(from, 0);
  89.     if (fromfd < 0)
  90.         fatal2("patch: internal error, can't reopen %s\n", from);
  91.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  92.         if (write(tofd, buf, i) != i)
  93.         fatal1("patch: write failed\n");
  94.     Close(fromfd);
  95.     Close(tofd);
  96.     }
  97.     Unlink(from);
  98. #endif
  99.     return 0;
  100. }
  101.  
  102. /* Copy a file. */
  103.  
  104. void
  105. copy_file(from,to)
  106. char *from, *to;
  107. {
  108.     Reg3 int tofd;
  109.     Reg2 int fromfd;
  110.     Reg1 int i;
  111.     
  112.     tofd = creat(to, 0666);
  113.     if (tofd < 0)
  114.     fatal2("patch: can't create %s.\n", to);
  115.     fromfd = open(from, 0);
  116.     if (fromfd < 0)
  117.     fatal2("patch: internal error, can't reopen %s\n", from);
  118.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  119.     if (write(tofd, buf, i) != i)
  120.         fatal2("patch: write (%s) failed\n", to);
  121.     Close(fromfd);
  122.     Close(tofd);
  123. }
  124.  
  125. /* Allocate a unique area for a string. */
  126.  
  127. char *
  128. savestr(s)
  129. Reg1 char *s;
  130. {
  131.     Reg3 char *rv;
  132.     Reg2 char *t;
  133.  
  134.     if (!s)
  135.     s = "Oops";
  136.     t = s;
  137.     while (*t++);
  138.     rv = malloc((MEM) (t - s));
  139.     if (rv == Nullch) {
  140.     if (using_plan_a)
  141.         out_of_mem = TRUE;
  142.     else
  143.         fatal1("patch: out of memory (savestr)\n");
  144.     }
  145.     else {
  146.     t = rv;
  147.     while (*t++ = *s++);
  148.     }
  149.     return rv;
  150. }
  151.  
  152. #if defined(lint) && defined(CANVARARG)
  153.  
  154. /*VARARGS ARGSUSED*/
  155. say(pat) char *pat; { ; }
  156. /*VARARGS ARGSUSED*/
  157. fatal(pat) char *pat; { ; }
  158. /*VARARGS ARGSUSED*/
  159. ask(pat) char *pat; { ; }
  160.  
  161. #else
  162.  
  163. /* Vanilla terminal output (buffered). */
  164.  
  165. void
  166. say(pat,arg1,arg2,arg3)
  167. char *pat;
  168. long arg1,arg2,arg3;
  169. {
  170.     fprintf(stderr, pat, arg1, arg2, arg3);
  171.     Fflush(stderr);
  172. }
  173.  
  174. /* Terminal output, pun intended. */
  175.  
  176. void                /* very void */
  177. fatal(pat,arg1,arg2,arg3)
  178. char *pat;
  179. long arg1,arg2,arg3;
  180. {
  181.     void my_exit();
  182.  
  183.     say(pat, arg1, arg2, arg3);
  184.     my_exit(1);
  185. }
  186.  
  187. /* Get a response from the user, somehow or other. */
  188.  
  189. void
  190. ask(pat,arg1,arg2,arg3)
  191. char *pat;
  192. long arg1,arg2,arg3;
  193. {
  194.     int ttyfd;
  195.     int r;
  196.     bool tty2 = isatty(2);
  197.  
  198.     Sprintf(buf, pat, arg1, arg2, arg3);
  199.     Fflush(stderr);
  200.     write(2, buf, strlen(buf));
  201.     if (tty2) {                /* might be redirected to a file */
  202.     r = read(2, buf, sizeof buf);
  203.     }
  204.     else if (isatty(1)) {        /* this may be new file output */
  205.     Fflush(stdout);
  206.     write(1, buf, strlen(buf));
  207.     r = read(1, buf, sizeof buf);
  208.     }
  209.     else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
  210.                     /* might be deleted or unwriteable */
  211.     write(ttyfd, buf, strlen(buf));
  212.     r = read(ttyfd, buf, sizeof buf);
  213.     Close(ttyfd);
  214.     }
  215.     else if (isatty(0)) {        /* this is probably patch input */
  216.     Fflush(stdin);
  217.     write(0, buf, strlen(buf));
  218.     r = read(0, buf, sizeof buf);
  219.     }
  220.     else {                /* no terminal at all--default it */
  221.     buf[0] = '\n';
  222.     r = 1;
  223.     }
  224.     if (r <= 0)
  225.     buf[0] = 0;
  226.     else
  227.     buf[r] = '\0';
  228.     if (!tty2)
  229.     say1(buf);
  230. }
  231. #endif /* lint */
  232.  
  233. /* How to handle certain events when not in a critical region. */
  234.  
  235. void
  236. set_signals(reset)
  237. int reset;
  238. {
  239.     void my_exit();
  240. #ifndef lint
  241. #ifdef VOIDSIG
  242.     static void (*hupval)(),(*intval)();
  243. #else
  244.     static int (*hupval)(),(*intval)();
  245. #endif
  246.  
  247.     if (!reset) {
  248.     hupval = signal(SIGHUP, SIG_IGN);
  249.     if (hupval != SIG_IGN)
  250. #ifdef VOIDSIG
  251.         hupval = my_exit;
  252. #else
  253.         hupval = (int(*)())my_exit;
  254. #endif
  255.     intval = signal(SIGINT, SIG_IGN);
  256.     if (intval != SIG_IGN)
  257. #ifdef VOIDSIG
  258.         intval = my_exit;
  259. #else
  260.         intval = (int(*)())my_exit;
  261. #endif
  262.     }
  263.     Signal(SIGHUP, hupval);
  264.     Signal(SIGINT, intval);
  265. #endif
  266. }
  267.  
  268. /* How to handle certain events when in a critical region. */
  269.  
  270. void
  271. ignore_signals()
  272. {
  273. #ifndef lint
  274.     Signal(SIGHUP, SIG_IGN);
  275.     Signal(SIGINT, SIG_IGN);
  276. #endif
  277. }
  278.  
  279. /* Make sure we'll have the directories to create a file. */
  280.  
  281. void
  282. makedirs(filename,striplast)
  283. Reg1 char *filename;
  284. bool striplast;
  285. {
  286.     char tmpbuf[256];
  287.     Reg2 char *s = tmpbuf;
  288.     char *dirv[20];
  289.     Reg3 int i;
  290.     Reg4 int dirvp = 0;
  291.  
  292.     while (*filename) {
  293.     if (*filename == '/') {
  294.         filename++;
  295.         dirv[dirvp++] = s;
  296.         *s++ = '\0';
  297.     }
  298.     else {
  299.         *s++ = *filename++;
  300.     }
  301.     }
  302.     *s = '\0';
  303.     dirv[dirvp] = s;
  304.     if (striplast)
  305.     dirvp--;
  306.     if (dirvp < 0)
  307.     return;
  308.     strcpy(buf, "mkdir");
  309.     s = buf;
  310.     for (i=0; i<=dirvp; i++) {
  311.     while (*s) s++;
  312.     *s++ = ' ';
  313.     strcpy(s, tmpbuf);
  314.     *dirv[i] = '/';
  315.     }
  316.     system(buf);
  317. }
  318.  
  319. /* Make filenames more reasonable. */
  320.  
  321. char *
  322. fetchname(at,strip_leading,assume_exists)
  323. char *at;
  324. int strip_leading;
  325. int assume_exists;
  326. {
  327.     char *s;
  328.     char *name;
  329.     Reg1 char *t;
  330.     char tmpbuf[200];
  331.  
  332.     if (!at)
  333.     return Nullch;
  334.     s = savestr(at);
  335.     for (t=s; isspace(*t); t++) ;
  336.     name = t;
  337. #ifdef DEBUGGING
  338.     if (debug & 128)
  339.     say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
  340. #endif
  341.     if (strnEQ(name, "/dev/null", 9))    /* so files can be created by diffing */
  342.     return Nullch;            /*   against /dev/null. */
  343.     for (; *t && !isspace(*t); t++)
  344.     if (*t == '/')
  345.         if (--strip_leading >= 0)
  346.         name = t+1;
  347.     *t = '\0';
  348.     if (name != s && *s != '/') {
  349.     name[-1] = '\0';
  350.     if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
  351.         name[-1] = '/';
  352.         name=s;
  353.     }
  354.     }
  355.     name = savestr(name);
  356.     Sprintf(tmpbuf, "RCS/%s", name);
  357.     free(s);
  358.     if (stat(name, &filestat) < 0 && !assume_exists) {
  359.     Strcat(tmpbuf, RCSSUFFIX);
  360.     if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
  361.         Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
  362.         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
  363.         free(name);
  364.         name = Nullch;
  365.         }
  366.     }
  367.     }
  368.     return name;
  369. }
  370.