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: }

Defined functions

build_new_rcs_file defined in line 359; used 1 times
collect_header defined in line 185; used 1 times
collect_userlist defined in line 166; used 1 times
concat defined in line 138; used 2 times
finalize_rcsfile defined in line 347; used 1 times
initialize_rcsfile defined in line 285; used 1 times
install_deltas defined in line 306; used 1 times
install_userlist defined in line 261; used 1 times
main defined in line 405; never used
new_delta defined in line 124; used 1 times
print_header defined in line 378; used 1 times
quit defined in line 77; used 6 times
read_sccs defined in line 240; used 1 times
sname defined in line 112; used 2 times
string defined in line 99; used 3 times
trimtail defined in line 156; used 1 times
xalloc defined in line 85; used 4 times

Defined variables

RCSid defined in line 1; never used
trace defined in line 53; used 12 times

Defined struct's

delta defined in line 56; used 2 times
  • in line 60(2)
header defined in line 69; never used
userlist defined in line 63; used 2 times
  • in line 66(2)

Defined typedef's

DELTA defined in line 61; used 8 times
HEADER defined in line 74; used 7 times
USERLIST defined in line 67; used 8 times

Defined macros

CI defined in line 47; used 1 times
FALSE defined in line 43; used 2 times
GET defined in line 46; used 1 times
RCS defined in line 45; used 3 times
SOH defined in line 44; used 3 times
TRUE defined in line 42; used 2 times
null defined in line 50; used 2 times
prefix defined in line 49; used 1 times
Last modified: 1984-10-31
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1758
Valid CSS Valid XHTML 1.0 Strict