|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.