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