home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / patch / util.c < prev    next >
C/C++ Source or Header  |  1990-03-24  |  11KB  |  537 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. char *strchr();
  9.  
  10. int
  11. move_file(from,to)
  12. char *from, *to;
  13. {
  14.     char bakname[512];
  15.     Reg1 char *s;
  16.     Reg2 int i;
  17.     Reg3 int fromfd;
  18.  
  19.     /* to stdout? */
  20.  
  21.     if (strEQ(to, "-")) {
  22. #ifdef DEBUGGING
  23.     if (debug & 4)
  24.         say2("Moving %s to stdout.\n", from);
  25. #endif
  26.         fromfd = open(from, O_RDONLY|O_BINARY);
  27.     if (fromfd < 0)
  28.         fatal2("patch: internal error, can't reopen %s\n", from);
  29.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  30.         if (write(1, buf, i) != 1)
  31.         fatal1("patch: write failed\n");
  32.     Close(fromfd);
  33.     return 0;
  34.     }
  35.  
  36.     if (origprae) {
  37.         Strcpy (bakname, origprae);
  38.         Strcat(bakname, to);
  39.     } else {
  40.         Strcpy(bakname, to);
  41. #ifdef MSDOS
  42.         if ((s=strchr(bakname,'.'))!=NULL)
  43.           *s=0;
  44. #endif
  45.         Strcat(bakname, origext?origext:ORIGEXT);
  46.     }
  47.  
  48.     if (stat(to, &filestat) >= 0) {    /* output file exists */
  49.     dev_t to_device = filestat.st_dev;
  50.     ino_t to_inode  = filestat.st_ino;
  51.     char *simplename = bakname;
  52.     
  53.         for (s=bakname; *s; s++) {
  54. #ifdef MSDOS
  55.             if (*s == '/' || *s == '\\')
  56. #else
  57.             if (*s == '/')
  58. #endif
  59.         simplename = s+1;
  60.     }
  61.     /* find a backup name that is not the same file */
  62.     while (stat(bakname, &filestat) >= 0 &&
  63.         to_device == filestat.st_dev && to_inode == filestat.st_ino) {
  64.         for (s=simplename; *s && !islower(*s); s++) ;
  65.         if (*s)
  66.         *s = toupper(*s);
  67.         else
  68.         Strcpy(simplename, simplename+1);
  69.     }
  70.  
  71.     while (unlink(bakname) >= 0) ;    /* while() is for benefit of Eunice */
  72.  
  73. #ifdef DEBUGGING
  74.     if (debug & 4)
  75.         say3("Moving %s to %s.\n", to, bakname);
  76. #endif
  77.  
  78. #ifdef MSDOS
  79.         if (rename(to, bakname) < 0) {
  80. #else
  81.     if (link(to, bakname) < 0) {
  82. #endif
  83.         say3("patch: can't backup %s, output is in %s\n",
  84.         to, from);
  85.         return -1;
  86.     }
  87.  
  88. #ifndef MSDOS
  89.     while (unlink(to) >= 0) ;
  90. #endif
  91.     }
  92.  
  93. #ifdef DEBUGGING
  94.     if (debug & 4)
  95.     say3("Moving %s to %s.\n", from, to);
  96. #endif
  97.  
  98. #ifdef MSDOS
  99.     if (rename(from, to) < 0) {           /* different file system? */
  100. #else
  101.     if (link(from, to) < 0) {        /* different file system? */
  102. #endif
  103.     Reg4 int tofd;
  104.     
  105.         tofd = open(to, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,S_IWRITE|S_IREAD);
  106.     if (tofd < 0) {
  107.         say3("patch: can't create %s, output is in %s.\n",
  108.           to, from);
  109.         return -1;
  110.     }
  111.  
  112.         fromfd = open(from, O_RDONLY|O_BINARY);
  113.     if (fromfd < 0)
  114.         fatal2("patch: internal error, can't reopen %s\n", from);
  115.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  116.         if (write(tofd, buf, i) != i)
  117.         fatal1("patch: write failed\n");
  118.     Close(fromfd);
  119.     Close(tofd);
  120. #ifdef MSDOS
  121.     Unlink(from);
  122.     }
  123. #else
  124.     }
  125.     Unlink(from);
  126. #endif
  127.     return 0;
  128. }
  129.  
  130. /* Copy a file. */
  131.  
  132. void
  133. copy_file(from,to)
  134. char *from, *to;
  135. {
  136.     Reg3 int tofd;
  137.     Reg2 int fromfd;
  138.     Reg1 int i;
  139.  
  140.     tofd = open(to, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,S_IWRITE|S_IREAD);
  141.     if (tofd < 0)
  142.     fatal2("patch: can't create %s.\n", to);
  143.     fromfd = open(from, O_RDONLY|O_BINARY);
  144.     if (fromfd < 0)
  145.     fatal2("patch: internal error, can't reopen %s\n", from);
  146.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  147.     if (write(tofd, buf, i) != i)
  148.         fatal2("patch: write (%s) failed\n", to);
  149.     Close(fromfd);
  150.     Close(tofd);
  151. }
  152.  
  153. /* Allocate a unique area for a string. */
  154.  
  155. char *
  156. savestr(s)
  157. Reg1 char *s;
  158. {
  159.     Reg3 char *rv;
  160.     Reg2 char *t;
  161.  
  162.     if (!s)
  163.     s = "Oops";
  164.     t = s;
  165.     while (*t++);
  166.     rv = malloc((MEM) (t - s));
  167.     if (rv == Nullch) {
  168.     if (using_plan_a)
  169.         out_of_mem = TRUE;
  170.     else
  171.         fatal1("patch: out of memory (savestr)\n");
  172.     }
  173.     else {
  174.     t = rv;
  175.     while (*t++ = *s++);
  176.     }
  177.     return rv;
  178. }
  179.  
  180. #if defined(lint) && defined(CANVARARG)
  181.  
  182. /*VARARGS ARGSUSED*/
  183. say(pat) char *pat; { ; }
  184. /*VARARGS ARGSUSED*/
  185. fatal(pat) char *pat; { ; }
  186. /*VARARGS ARGSUSED*/
  187. ask(pat) char *pat; { ; }
  188.  
  189. #else
  190.  
  191. /* Vanilla terminal output (buffered). */
  192.  
  193. #ifdef MSDOS
  194. #include <stdarg.h>
  195.  
  196. void say(char *pat,...)
  197. {
  198.     va_list argptr;
  199.  
  200.     va_start(argptr, pat);
  201.     vfprintf(stderr, pat, argptr);
  202.     va_end(argptr);
  203.     Fflush(stderr);
  204. }
  205.  
  206. void fatal(char *pat,...)
  207. {
  208.     void my_exit();
  209.     va_list argptr;
  210.  
  211.     va_start(argptr, pat);
  212.     vfprintf(stderr, pat, argptr);
  213.     va_end(argptr);
  214.     Fflush(stderr);
  215.     my_exit(1);
  216. }
  217.  
  218. #else
  219. void
  220. say(pat,arg1,arg2,arg3)
  221. char *pat;
  222. long arg1,arg2,arg3;
  223. {
  224.     fprintf(stderr, pat, arg1, arg2, arg3);
  225.     Fflush(stderr);
  226. }
  227.  
  228. /* Terminal output, pun intended. */
  229.  
  230. void                /* very void */
  231. fatal(pat,arg1,arg2,arg3)
  232. char *pat;
  233. long arg1,arg2,arg3;
  234. {
  235.     void my_exit();
  236.  
  237.     say(pat, arg1, arg2, arg3);
  238.     my_exit(1);
  239. }
  240. #endif
  241.  
  242. /* Get a response from the user, somehow or other. */
  243.  
  244. #ifdef MSDOS
  245. void ask(char *pat,...)
  246. {
  247.     int ttyfd;
  248.     int r;
  249.     bool tty2 = isatty(2);
  250.     va_list argptr;
  251.  
  252.     va_start(argptr, pat);
  253.     vsprintf(buf, pat, argptr);
  254.     va_end(argptr);
  255. #else
  256. void
  257. ask(pat,arg1,arg2,arg3)
  258. char *pat;
  259. long arg1,arg2,arg3;
  260. {
  261.     int ttyfd;
  262.     int r;
  263.     bool tty2 = isatty(2);
  264.  
  265.     Sprintf(buf, pat, arg1, arg2, arg3);
  266. #endif
  267.     Fflush(stderr);
  268.     write(2, buf, strlen(buf));
  269.     if (tty2) {                /* might be redirected to a file */
  270.     r = read(2, buf, sizeof buf);
  271.     }
  272.     else if (isatty(1)) {        /* this may be new file output */
  273.     Fflush(stdout);
  274.     write(1, buf, strlen(buf));
  275.     r = read(1, buf, sizeof buf);
  276.     }
  277. #ifdef MSDOS
  278.     else if ((ttyfd = open("con", O_RDWR)) >= 0 && isatty(ttyfd)) {
  279. #else
  280.     else if ((ttyfd = open("/dev/tty", O_RDWR)) >= 0 && isatty(ttyfd)) {
  281. #endif
  282.                     /* might be deleted or unwriteable */
  283.     write(ttyfd, buf, strlen(buf));
  284.     r = read(ttyfd, buf, sizeof buf);
  285.     Close(ttyfd);
  286.     }
  287.     else if (isatty(0)) {        /* this is probably patch input */
  288.     Fflush(stdin);
  289.     write(0, buf, strlen(buf));
  290.     r = read(0, buf, sizeof buf);
  291.     }
  292.     else {                /* no terminal at all--default it */
  293.     buf[0] = '\n';
  294.     r = 1;
  295.     }
  296.     if (r <= 0)
  297.     buf[0] = 0;
  298.     else
  299.     buf[r] = '\0';
  300.     if (!tty2)
  301.     say1(buf);
  302. }
  303. #endif /* lint */
  304.  
  305. /* How to handle certain events when not in a critical region. */
  306.  
  307. void
  308. set_signals(reset)
  309. int reset;
  310. {
  311.     void my_exit();
  312. #ifndef lint
  313. #ifdef VOIDSIG
  314.     static void (*hupval)(),(*intval)();
  315. #else
  316.     static int (*hupval)(),(*intval)();
  317. #endif
  318.  
  319.     if (!reset) {
  320. #ifndef MSDOS
  321.     hupval = signal(SIGHUP, SIG_IGN);
  322.     if (hupval != SIG_IGN)
  323. #ifdef VOIDSIG
  324.         hupval = my_exit;
  325. #else
  326.         hupval = (int(*)())my_exit;
  327. #endif
  328. #endif
  329.     intval = signal(SIGINT, SIG_IGN);
  330.     if (intval != SIG_IGN)
  331. #ifdef VOIDSIG
  332.         intval = my_exit;
  333. #else
  334.         intval = (int(*)())my_exit;
  335. #endif
  336.     }
  337. #ifndef MSDOS
  338.     Signal(SIGHUP, hupval);
  339. #endif
  340.     Signal(SIGINT, intval);
  341. #endif
  342. }
  343.  
  344. /* How to handle certain events when in a critical region. */
  345.  
  346. void
  347. ignore_signals()
  348. {
  349. #ifndef lint
  350. #ifndef MSDOS
  351.     Signal(SIGHUP, SIG_IGN);
  352. #endif
  353.     Signal(SIGINT, SIG_IGN);
  354. #endif
  355. }
  356.  
  357. /* Make sure we'll have the directories to create a file. */
  358.  
  359. void
  360. makedirs(filename,striplast)
  361. Reg1 char *filename;
  362. bool striplast;
  363. {
  364.     char tmpbuf[256];
  365.     Reg2 char *s = tmpbuf;
  366.     char *dirv[20];
  367.     Reg3 int i;
  368.     Reg4 int dirvp = 0;
  369.  
  370.     while (*filename) {
  371. #ifdef MSDOS
  372.         if (*filename == '/' || *filename == '\\') {
  373. #else
  374.         if (*filename == '/') {
  375. #endif
  376.         filename++;
  377.         dirv[dirvp++] = s;
  378.         *s++ = '\0';
  379.     }
  380.     else {
  381.         *s++ = *filename++;
  382.     }
  383.     }
  384.     *s = '\0';
  385.     dirv[dirvp] = s;
  386.     if (striplast)
  387.     dirvp--;
  388.     if (dirvp < 0)
  389.     return;
  390.     strcpy(buf, "mkdir");
  391.     s = buf;
  392.     for (i=0; i<=dirvp; i++) {
  393.     while (*s) s++;
  394.     *s++ = ' ';
  395.     strcpy(s, tmpbuf);
  396.     *dirv[i] = '/';
  397.     }
  398.     system(buf);
  399. }
  400.  
  401. /* Make filenames more reasonable. */
  402.  
  403. char *
  404. fetchname(at,strip_leading,assume_exists)
  405. char *at;
  406. int strip_leading;
  407. int assume_exists;
  408. {
  409.     char *s;
  410.     char *name;
  411.     Reg1 char *t;
  412.     char tmpbuf[200];
  413.  
  414.     if (!at)
  415.     return Nullch;
  416.     s = savestr(at);
  417.     for (t=s; isspace(*t); t++) ;
  418.     name = t;
  419. #ifdef DEBUGGING
  420.     if (debug & 128)
  421.     say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
  422. #endif
  423.     if (strnEQ(name, "/dev/null", 9))    /* so files can be created by diffing */
  424.     return Nullch;            /*   against /dev/null. */
  425.     for (; *t && !isspace(*t); t++)
  426. #ifdef MSDOS
  427.         if (*t == '/' || *t == '\\')
  428. #else
  429.         if (*t == '/')
  430. #endif
  431.         if (--strip_leading >= 0)
  432.         name = t+1;
  433.     *t = '\0';
  434. #ifdef MSDOS
  435.     if (name != s && *s != '/' && *s != '\\') {
  436. #else
  437.     if (name != s && *s != '/') {
  438. #endif
  439.     name[-1] = '\0';
  440.     if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
  441.         name[-1] = '/';
  442.         name=s;
  443.     }
  444.     }
  445.     name = savestr(name);
  446.     Sprintf(tmpbuf, "RCS/%s", name);
  447.     free(s);
  448.     if (stat(name, &filestat) < 0 && !assume_exists) {
  449.     Strcat(tmpbuf, RCSSUFFIX);
  450.     if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
  451.         Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
  452.         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
  453.         free(name);
  454.         name = Nullch;
  455.         }
  456.     }
  457.     }
  458.     return name;
  459. }
  460.  
  461.  
  462. #ifdef MSDOS
  463.  
  464. char *getenv();
  465.  
  466. Mktemp(char *file)
  467. {
  468.   char fname[32], *tmp;
  469.  
  470.   tmp = getenv("TMP");
  471.  
  472.   if ( tmp != NULL )
  473.   {
  474.     strcpy(fname, file);
  475.     strcpy(file, tmp);
  476.  
  477.     if ( file[strlen(file) - 1] != '\\' )
  478.       strcat(file, "\\");
  479.  
  480.     strcat(file, fname);
  481.   }
  482.  
  483.   mktemp(file);
  484. }
  485.  
  486. /* only one pipe can be open at a time */
  487.  
  488. static char pipename[128], command[128];
  489. static int wrpipe;
  490.  
  491. FILE *popen(char *cmd, char *flags)
  492. {
  493.   wrpipe = (strchr(flags, 'w') != NULL);
  494.  
  495.   if ( wrpipe )
  496.   {
  497.     strcpy(command, cmd);
  498.     strcpy(pipename, "~WXXXXXX");
  499.     Mktemp(pipename);
  500.     return fopen(pipename, flags);  /* ordinary file */
  501.   }
  502.   else
  503.   {
  504.     strcpy(pipename, "~RXXXXXX");
  505.     Mktemp(pipename);
  506.     strcpy(command, cmd);
  507.     strcat(command, ">");
  508.     strcat(command, pipename);
  509.     system(command);
  510.     return fopen(pipename, flags);  /* ordinary file */
  511.   }
  512. }
  513.  
  514. int pclose(FILE *pipe)
  515. {
  516.   int rc;
  517.  
  518.   if ( fclose(pipe) == EOF )
  519.     return EOF;
  520.  
  521.   if ( wrpipe )
  522.   {
  523.     strcat(command, "<");
  524.     strcat(command, pipename);
  525.     rc = system(command);
  526.     unlink(pipename);
  527.     return rc;
  528.   }
  529.   else
  530.   {
  531.     unlink(pipename);
  532.     return 0;
  533.   }
  534. }
  535.  
  536. #endif
  537.