home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / rcs / sources / mkmodule.c < prev    next >
C/C++ Source or Header  |  1992-01-19  |  6KB  |  244 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Id: mkmodules.c,v 1.9 89/11/19 23:20:10 berliner Exp $";
  3. #endif
  4.  
  5. /*
  6.  *    Copyright (c) 1989, Brian Berliner
  7.  *
  8.  *    You may distribute under the terms of the GNU General Public License
  9.  *    as specified in the README file that comes with the CVS 1.0 kit.
  10.  *
  11.  * mkmodules
  12.  *
  13.  *    Re-build the modules database for the CVS system.  Accepts one
  14.  *    argument, which is the directory that the modules,v file lives in.
  15.  */
  16.  
  17. #include <fcntl.h>
  18. #include <signal.h>
  19. #include <ctype.h>
  20. #include "cvs.h"
  21.  
  22. char *progname;
  23.  
  24. char prog[MAXPROGLEN];
  25. char *Rcsbin = RCSBIN_DFLT;
  26.  
  27. main(argc, argv)
  28.     int argc;
  29.     char *argv[];
  30. {
  31.     extern char *getenv();
  32.     char temp[50];
  33.     char *cp;
  34.  
  35.     /*
  36.      * Just save the last component of the path for error messages
  37.      */
  38.     if ((progname = rindex_sep(argv[0])) == NULL)
  39.     progname = argv[0];
  40.     else
  41.     progname++;
  42.  
  43.     if (argc != 2)
  44.     mkmodules_usage();
  45.  
  46.     if ((cp = getenv(RCSBIN_ENV)) != NULL)
  47.     Rcsbin = cp;
  48.  
  49.     if (chdir(argv[1]) < 0)
  50.     error(1, "cannot chdir to %s", argv[1]);
  51.     /*
  52.      * First, do the work necessary to update the "modules" database.
  53.      */
  54.     make_tempfile(CVSMODULE_TMP, temp);
  55.     if (checkout_file(CVSMODULE_FILE, temp) == 0) {
  56.     write_dbmfile(temp);
  57.     rename_dbmfile(temp);
  58.     }
  59.     (void) unlink(temp);
  60.     /*
  61.      * Now, check out the "loginfo" file, so that it is always up-to-date
  62.      * in the CVSROOT.adm directory.
  63.      */
  64.     make_tempfile(CVSLOGINFO_TMP, temp);
  65.     if (checkout_file(CVSLOGINFO_FILE, temp) == 0)
  66.     rename_loginfo(temp);
  67.     (void) unlink(temp);
  68.     exit(0);
  69. }
  70.  
  71. static
  72. make_tempfile(file, temp)
  73.     char *file;
  74.     char *temp;
  75. {
  76.     int fd;
  77.  
  78.     (void) strcpy(temp, file);
  79.     if ((fd = mkstemp(temp)) < 0)
  80.     error(1, "cannot create temporary file %s", temp);
  81.     (void) close(fd);
  82. }
  83.  
  84. static
  85. checkout_file(file, temp)
  86.     char *file;
  87.     char *temp;
  88. {
  89.     (void) sprintf(prog, "%s -q -p %s >%s", RCS_CO, file, temp);
  90.     if (system(prog) != 0) {
  91.     warn(0, "failed to check out %s file", file);
  92.     return (1);
  93.     }
  94.     return (0);
  95. }
  96.  
  97. static
  98. write_dbmfile(temp)
  99.     char *temp;
  100. {
  101.     char line[DBLKSIZ], value[DBLKSIZ];
  102.     FILE *fp;
  103.     DBM *db;
  104.     char *cp, *vp;
  105.     datum key, val;
  106.     int len, cont, err = 0;
  107.  
  108.     fp = open_file(temp, "r");
  109.     if ((db = dbm_open(temp, O_RDWR|O_CREAT|O_TRUNC, 0666)) == NULL)
  110.     error(1, "cannot open dbm file %s for creation", temp);
  111.     for (cont = 0; fgets(line, sizeof(line), fp) != NULL; ) {
  112.     if ((cp = rindex(line, '\n')) != NULL)
  113.         *cp = '\0';            /* strip the newline */
  114.     /*
  115.      * Add the line to the value, at the end if this is a continuation
  116.      * line; otherwise at the beginning, but only after any trailing
  117.      * backslash is removed.
  118.      */
  119.     vp = value;
  120.     if (cont)
  121.         vp += strlen(value);
  122.     /*
  123.      * See if the line we read is a continuation line, and strip the
  124.      * backslash if so.
  125.      */
  126.     len = strlen(line);
  127.     if (len > 0)
  128.         cp = &line[len-1];
  129.     else
  130.         cp = line;
  131.     if (*cp == '\\') {
  132.         cont = 1;
  133.         *cp = '\0';
  134.     } else {
  135.         cont = 0;
  136.     }
  137.     (void) strcpy(vp, line);
  138.     if (value[0] == '#')
  139.         continue;            /* comment line */
  140.     vp = value;
  141.     while (*vp && isspace(*vp))
  142.         vp++;
  143.     if (*vp == '\0')
  144.         continue;            /* empty line */
  145.     /*
  146.      * If this was not a continuation line, add the entry to the database
  147.      */
  148.     if (!cont) {
  149.         key.dptr = vp;
  150.         while (*vp && !isspace(*vp))
  151.         vp++;
  152.         key.dsize = vp - key.dptr;
  153.         *vp++ = '\0';        /* NULL terminate the key */
  154.         while (*vp && isspace(*vp))
  155.         vp++;            /* skip whitespace to value */
  156.         if (*vp == '\0') {
  157.         warn(0, "warning: NULL value for key '%s'", key.dptr);
  158.         continue;
  159.         }
  160.         val.dptr = vp;
  161.         val.dsize = strlen(vp);
  162.         if (dbm_store(db, key, val, DBM_INSERT) == 1) {
  163.         warn(0, "duplicate key found for '%s'", key.dptr);
  164.         err++;
  165.         }
  166.     }
  167.     }
  168.     dbm_close(db);
  169.     (void) fclose(fp);
  170.     (void) unlink(temp);
  171.     if (err) {
  172.     char dotdir[50], dotpag[50];
  173.  
  174.     (void) sprintf(dotdir, "%s.dir", temp);
  175.     (void) sprintf(dotpag, "%s.pag", temp);
  176.     (void) unlink(dotdir);
  177.     (void) unlink(dotpag);
  178.     error(0, "DBM creation failed; correct above errors");
  179.     }
  180. }
  181.  
  182. static
  183. rename_dbmfile(temp)
  184.     char *temp;
  185. {
  186.     char newdir[50], newpag[50];
  187.     char dotdir[50], dotpag[50];
  188.     char bakdir[50], bakpag[50];
  189.  
  190.     (void) signal(SIGINT, SIG_IGN);    /* don't mess with me... */
  191.     (void) signal(SIGTERM, SIG_IGN);
  192.     (void) signal(SIGBREAK, SIG_IGN);
  193.  
  194.     (void) sprintf(dotdir, "%s.dir", CVSMODULE_FILE);
  195.     (void) sprintf(dotpag, "%s.pag", CVSMODULE_FILE);
  196.     (void) sprintf(bakdir, "%s%s.dir", BAKPREFIX, CVSMODULE_FILE);
  197.     (void) sprintf(bakpag, "%s%s.pag", BAKPREFIX, CVSMODULE_FILE);
  198.     (void) sprintf(newdir, "%s.dir", temp);
  199.     (void) sprintf(newpag, "%s.pag", temp);
  200.  
  201.     (void) chmod(newdir, 0666);
  202.     (void) chmod(newpag, 0666);
  203.  
  204.     (void) unlink(bakdir);        /* rm .#modules.dir .#modules.pag */
  205.     (void) unlink(bakpag);
  206.     (void) rename(dotdir, bakdir);    /* mv modules.dir .#modules.dir */
  207.     (void) rename(dotpag, bakpag);    /* mv modules.pag .#modules.pag */
  208.     (void) rename(newdir, dotdir);    /* mv "temp".dir modules.dir */
  209.     (void) rename(newpag, dotpag);    /* mv "temp".pag modules.pag */
  210. }
  211.  
  212. static
  213. rename_loginfo(temp)
  214.     char *temp;
  215. {
  216.     char bak[50];
  217.  
  218.     if (chmod(temp, 0666) < 0)            /* chmod 666 "temp" */
  219.     warn(1, "warning: cannot chmod %s", temp);
  220.     (void) sprintf(bak, "%s%s", BAKPREFIX, CVSLOGINFO_FILE);
  221.     (void) unlink(bak);                /* rm .#loginfo */
  222.     (void) rename(CVSLOGINFO_FILE, bak);    /* mv loginfo .#loginfo */
  223.     (void) rename(temp, CVSLOGINFO_FILE);    /* mv "temp" loginfo */
  224. }
  225.  
  226. /*
  227.  * For error() only
  228.  */
  229. void
  230. Lock_Cleanup(sig)
  231. int sig;
  232. {
  233. #ifdef lint
  234.     sig = sig;
  235. #endif
  236. }
  237.  
  238. static
  239. mkmodules_usage()
  240. {
  241.     (void) fprintf(stderr, "Usage: %s modules-directory\n", progname);
  242.     exit(1);
  243. }
  244.