Annotation of 43BSDReno/contrib/patch/util.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.