|
|
1.1 ! root 1: static char *RCSid = ! 2: "$Header: sccstorcs.c,v 1.4 84/10/17 21:12:11 root Exp $"; ! 3: ! 4: /* ! 5: * SCCSTORCS - build RCS file from SCCS file preserving deltas. ! 6: * Author: Ken Greer ! 7: * ! 8: * Copyright (c) 1983 by Kenneth L. Greer ! 9: * ! 10: * All rights reserved. No part of this software may be sold or distributed ! 11: * in any form or by any means without the prior written permission of the ! 12: * author. ! 13: * ! 14: * $Log: sccstorcs.c,v $ ! 15: * Revision 1.4 84/10/17 21:12:11 root ! 16: * Added check for having multiple deltas in a row for the same revision. ! 17: * --ks ! 18: * ! 19: * Revision 1.3 84/10/17 20:53:18 root ! 20: * Put in SCCS string in comment for telling who checked it in.. ! 21: * --ks ! 22: * ! 23: * Revision 1.2 84/10/17 12:22:14 root ! 24: * Fixed the case when a delta was removed. ! 25: * Also, use -f on checkin so comments are kept even if the file ! 26: * didn't change between deltas. ! 27: * --ks ! 28: * ! 29: * Revision 1.1 84/10/07 14:59:47 root ! 30: * Initial revision ! 31: * ! 32: * Revision 1.2 83/03/27 11:21:17 root ! 33: * Returns non-zero exit codes on soft errors also. ! 34: * ! 35: * Revision 1.1 83/03/24 14:33:24 root ! 36: * Initial revision ! 37: * ! 38: */ ! 39: ! 40: #include <stdio.h> ! 41: ! 42: #define TRUE 1 ! 43: #define FALSE 0 ! 44: #define SOH 001 /* SCCS lines start with SOH (Control-A) */ ! 45: #define RCS "rcs -q" ! 46: #define GET "get -s" ! 47: #define CI "ci -q -f" ! 48: ! 49: #define prefix(a, b) (strncmp(a, b, strlen(a)) == 0) ! 50: #define null(str) ((str) == NULL ? "<null>\n" : (str)) ! 51: ! 52: int ! 53: trace = FALSE, /* just show what would be done, don't run commands */ ! 54: verbose = FALSE; /* Print commands before executing */ ! 55: ! 56: typedef struct delta ! 57: { ! 58: char *revision; ! 59: char *commentary; ! 60: struct delta *next; ! 61: } DELTA; ! 62: ! 63: typedef struct userlist ! 64: { ! 65: char *user; ! 66: struct userlist *next; ! 67: } USERLIST; ! 68: ! 69: typedef struct header ! 70: { ! 71: DELTA *deltas; ! 72: USERLIST *userlist; ! 73: char *description; ! 74: } HEADER; ! 75: ! 76: ! 77: quit (fmt, args) ! 78: char *fmt; ! 79: { ! 80: fprintf (stderr, "sccstorcs: "); ! 81: _doprnt(fmt, &args, stderr); ! 82: exit (1); ! 83: } ! 84: ! 85: char * ! 86: xalloc (size) ! 87: unsigned size; ! 88: { ! 89: extern char *malloc (); ! 90: char *p; ! 91: if ((p = malloc (size)) == NULL) ! 92: quit ("Out of Memory.\n"); ! 93: return (p); ! 94: } ! 95: ! 96: /* ! 97: * Allocate space for string and copy str to it. ! 98: */ ! 99: char * ! 100: string (str) ! 101: char *str; ! 102: { ! 103: register char *p = xalloc ((unsigned) (strlen (str) + 1)); ! 104: strcpy (p, str); ! 105: return (p); ! 106: } ! 107: ! 108: /* ! 109: * Return pointer to the final file name in a path. ! 110: * I.e. sname ("/foo/baz/mumble") returns a pointer to "mumble". ! 111: */ ! 112: char * ! 113: sname (s) ! 114: register char *s; ! 115: { ! 116: register char *p; ! 117: ! 118: for (p = s; *p;) ! 119: if (*p++ == '/') ! 120: s = p; ! 121: return (s); ! 122: } ! 123: ! 124: DELTA * ! 125: new_delta (line) ! 126: char *line; ! 127: { ! 128: register DELTA *delta; ! 129: char rev[32]; ! 130: ! 131: sscanf (line, "%*s %*s %s", rev); ! 132: delta = (DELTA *) xalloc (sizeof (DELTA)); ! 133: delta -> revision = string (rev); ! 134: delta -> commentary = NULL; ! 135: return (delta); ! 136: } ! 137: ! 138: char * ! 139: concat (old_str, str) ! 140: char *old_str, *str; ! 141: { ! 142: register int len; ! 143: register char *newstring; ! 144: ! 145: if (old_str == NULL) ! 146: return (string (str)); ! 147: ! 148: len = strlen (old_str) + strlen (str); ! 149: newstring = (char *) xalloc ((unsigned) (len + 1)); ! 150: strcpy (newstring, old_str); ! 151: strcat (newstring, str); ! 152: free (old_str); ! 153: return (newstring); ! 154: } ! 155: ! 156: trimtail (line) ! 157: char *line; ! 158: { ! 159: register char *p = line; ! 160: while (*p) p++; ! 161: while (p > line && p[-1] <= ' ') ! 162: p--; ! 163: *p = '\0'; ! 164: } ! 165: ! 166: USERLIST * ! 167: collect_userlist (fd) ! 168: FILE *fd; ! 169: { ! 170: char line[128]; ! 171: USERLIST *userlist = NULL, *newuser; ! 172: while (fgets (line, sizeof line, fd)) ! 173: { ! 174: if (line[0] == SOH && line[1] == 'U') /* End of userlist */ ! 175: break; ! 176: trimtail (line); ! 177: newuser = (USERLIST *) xalloc (sizeof (USERLIST)); ! 178: newuser -> user = string (line); ! 179: newuser -> next = userlist; ! 180: userlist = newuser; ! 181: } ! 182: return (userlist); ! 183: } ! 184: ! 185: HEADER * ! 186: collect_header (fd) ! 187: FILE *fd; ! 188: { ! 189: DELTA *head = NULL, *delta; ! 190: USERLIST *userlist = NULL; ! 191: static HEADER header; ! 192: char line[512], *description = NULL; ! 193: while (fgets (line, sizeof line, fd)) ! 194: { ! 195: if (line[0] != SOH) ! 196: continue; ! 197: if (line[1] == 'I') /* The first INCLUDE */ ! 198: break; ! 199: switch (line[1]) ! 200: { ! 201: case 'd': /* New delta */ ! 202: #ifdef PURDUE_EE ! 203: if (line[3] == 'R') ! 204: while (fgets (line, sizeof line, fd)) ! 205: if (line[0] == SOH && line[1] == 'd' && line[3] != 'R') ! 206: break; ! 207: #endif ! 208: delta = new_delta (line); ! 209: #ifdef PURDUE_EE ! 210: if (!head || strcmp(delta -> revision, head -> revision)) { ! 211: #endif ! 212: delta -> next = head; ! 213: head = delta; ! 214: #ifdef PURDUE_EE ! 215: } ! 216: #endif ! 217: #ifndef PURDUE_EE ! 218: break; ! 219: #endif ! 220: case 'c': /* Commentary */ ! 221: delta -> commentary = concat (delta -> commentary, &line[3]); ! 222: break; ! 223: case 'u': ! 224: userlist = collect_userlist (fd); ! 225: break; ! 226: case 't': ! 227: while (fgets (line, sizeof line, fd) && !prefix("\1T", line)) ! 228: description = concat (description, line); ! 229: } ! 230: } ! 231: header.userlist = userlist; ! 232: header.deltas = head; ! 233: header.description = description; ! 234: return (&header); ! 235: } ! 236: ! 237: /* ! 238: * Convert SCCS file to RCS file ! 239: */ ! 240: HEADER * ! 241: read_sccs (sccsfile) ! 242: char *sccsfile; ! 243: { ! 244: HEADER *header; ! 245: FILE *fd; ! 246: if (strncmp (sname (sccsfile), "s.", 2) != 0) /* An SCCS file? */ ! 247: { ! 248: fprintf (stderr, "%s: not an SCCS file.\n", sccsfile); ! 249: return (NULL); ! 250: } ! 251: if ((fd = fopen (sccsfile, "r")) == NULL) ! 252: { ! 253: fprintf (stderr, "%s: cannot open.\n", sccsfile); ! 254: return (NULL); ! 255: } ! 256: header = collect_header (fd); ! 257: fclose (fd); ! 258: return (header); ! 259: } ! 260: ! 261: install_userlist (userlist, rcsfile) ! 262: register USERLIST *userlist; ! 263: char *rcsfile; ! 264: { ! 265: char command[512]; ! 266: int count; ! 267: if (userlist == NULL) ! 268: return (0); ! 269: sprintf (command, "%s -a", RCS); ! 270: for (count = 0; userlist; userlist = userlist -> next, count++) ! 271: { ! 272: if (count > 0) ! 273: strcat (command, ","); ! 274: strcat (command, userlist -> user); ! 275: } ! 276: strcat (command, " "); ! 277: strcat (command, rcsfile); ! 278: if (trace || verbose) ! 279: printf ("%% %s\n", command); ! 280: if (trace) ! 281: return (0); ! 282: return (system (command)); ! 283: } ! 284: ! 285: initialize_rcsfile (description, rcsfile) ! 286: char *description, *rcsfile; ! 287: { ! 288: char command[512]; ! 289: extern FILE *popen(); ! 290: FILE *pd; ! 291: ! 292: sprintf (command, "%s -i -U %s", RCS, rcsfile); ! 293: if (trace || verbose) ! 294: printf ("%% %s\n", command); ! 295: if (trace) ! 296: { ! 297: printf ("Description:\n%s\n", null(description)); ! 298: return (0); ! 299: } ! 300: if ((pd = popen (command, "w")) == NULL) ! 301: return (-1); ! 302: fprintf (pd, "%s", description ? description : "\n"); ! 303: return (pclose (pd)); ! 304: } ! 305: ! 306: install_deltas (delta, sccsfile, rcsfile) ! 307: register DELTA *delta; ! 308: char *sccsfile, *rcsfile; ! 309: { ! 310: char command[512]; ! 311: for (; delta; delta = delta -> next) ! 312: { ! 313: /* ! 314: * Get the SCCS file. ! 315: */ ! 316: sprintf (command, "%s -p -r%s %s > %s", ! 317: GET, delta -> revision, sccsfile, rcsfile); ! 318: if (trace || verbose) ! 319: printf("%% %s\n", command); ! 320: if (!trace) ! 321: { ! 322: if (system (command)) ! 323: return (-1); ! 324: } ! 325: ! 326: sprintf (command, "%s -r%s %s", CI, delta -> revision, rcsfile); ! 327: if (trace || verbose) ! 328: printf("%% %s\n", command); ! 329: if (trace) ! 330: printf("Commentary:\n%s\n", null(delta -> commentary)); ! 331: else ! 332: { ! 333: extern FILE *popen (); ! 334: FILE *pd; ! 335: int x; ! 336: if ((pd = popen (command, "w")) == NULL) ! 337: return (-1); ! 338: if (delta -> commentary) ! 339: fprintf (pd, delta -> commentary); ! 340: if ((x = pclose (pd)) != 0) ! 341: return (x); ! 342: } ! 343: } ! 344: return (0); ! 345: } ! 346: ! 347: finalize_rcsfile (rcsfile) ! 348: char *rcsfile; ! 349: { ! 350: char command[512]; ! 351: sprintf (command, "%s -L %s", RCS, rcsfile); ! 352: if (trace || verbose) ! 353: printf ("%% %s\n", command); ! 354: if (trace) ! 355: return (0); ! 356: return (system (command)); ! 357: } ! 358: ! 359: build_new_rcs_file (header, sccsfile) ! 360: HEADER *header; ! 361: char *sccsfile; ! 362: { ! 363: char *rcsfile = &(sname (sccsfile))[2]; ! 364: ! 365: if (initialize_rcsfile (header -> description, rcsfile)) ! 366: quit ("Error initializing new rcs file %s\n", rcsfile); ! 367: ! 368: if (install_userlist (header -> userlist, rcsfile)) ! 369: quit ("Error installing user access list to rcs file %s\n", rcsfile); ! 370: ! 371: if (install_deltas (header -> deltas, sccsfile, rcsfile)) ! 372: quit ("Error installing delta to rcs file %s\n", rcsfile); ! 373: ! 374: if (finalize_rcsfile (rcsfile)) ! 375: quit ("Error setting defaults to rcs file %s\n", rcsfile); ! 376: } ! 377: ! 378: print_header (sccsfile, header) ! 379: char *sccsfile; ! 380: register HEADER *header; ! 381: { ! 382: register DELTA *d; ! 383: register USERLIST *u; ! 384: ! 385: printf ("\n%s:\n", sccsfile); ! 386: printf ("------------------------------------------------------------\n"); ! 387: if (header -> description) ! 388: printf ("Descriptive text:\n%s", header -> description); ! 389: ! 390: if (header -> userlist) ! 391: { ! 392: printf ("\nUser access list:\n"); ! 393: for (u = header -> userlist; u; u = u -> next) ! 394: printf ("%s\n", u -> user); ! 395: } ! 396: ! 397: for (d = header -> deltas; d; d = d -> next) ! 398: { ! 399: printf ("\nRelease: %s\n", d -> revision); ! 400: printf ("Commentary:\n%s", d -> commentary); ! 401: } ! 402: printf ("------------------------------------------------------------\n"); ! 403: } ! 404: ! 405: main (argc, argv) ! 406: char **argv; ! 407: { ! 408: int errors = 0; ! 409: ! 410: for (; argc > 1 && argv[1][0] == '-'; argc--, argv++) ! 411: { ! 412: switch (argv[1][1]) ! 413: { ! 414: case 'v': ! 415: verbose = TRUE; ! 416: break; ! 417: case 't': ! 418: trace = TRUE; ! 419: break; ! 420: default: ! 421: fprintf (stderr, "Unknown switch \"%s\".\n", argv[1]); ! 422: exit (1); ! 423: } ! 424: } ! 425: ! 426: if (argc <= 1) ! 427: quit ("Usage: sccstorcs [-t -v] s.file ...\n"); ! 428: ! 429: for (; argc > 1; argc--, argv++) ! 430: { ! 431: HEADER *header; ! 432: char *sccsfile; ! 433: sccsfile = argv[1]; ! 434: if ((header = read_sccs (sccsfile)) != NULL) ! 435: { ! 436: if (trace) ! 437: print_header (sccsfile, header); ! 438: build_new_rcs_file (header, sccsfile); ! 439: } ! 440: else ! 441: errors++; ! 442: } ! 443: exit (errors); ! 444: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.