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