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

  1. #ifndef lint
  2. static char rcsid[] = "$Id: modules.c,v 1.14.1.1 91/01/29 07:17:32 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.  * Modules
  12.  *
  13.  *    Functions for accessing the modules file.
  14.  *
  15.  *    The modules file supports basically three formats of lines:
  16.  *        key [options] directory files...
  17.  *        key [options] directory
  18.  *        key -a aliases...
  19.  *
  20.  *    The -a option allows an aliasing step in the parsing of the modules
  21.  *    file.  The "aliases" listed on a line following the -a are
  22.  *    processed one-by-one, as if they were specified as arguments on the
  23.  *    command line.
  24.  */
  25.  
  26. #include <fcntl.h>
  27. #include "cvs.h"
  28.  
  29. extern int update_build_dirs;
  30.  
  31. int run_module_prog = 1;        /* run -i/-o/-t prog by default */
  32.  
  33. /*
  34.  * Open the modules file, and die if the CVSROOT environment variable
  35.  * was not set.  If the modules file does not exist, that's fine, and
  36.  * a warning message is displayed and a NULL is returned.
  37.  */
  38. DBM *
  39. open_module()
  40. {
  41.     char mfile[MAXPATHLEN];
  42.     DBM *db;
  43.  
  44.     if (CVSroot == NULL) {
  45.     (void) fprintf(stderr, "%s: must set the CVSROOT environment variable\n",
  46.                progname);
  47.     error(0, "or specify the '-d' option to %s", progname);
  48.     }
  49.     (void) sprintf(mfile, "%s%c%s", CVSroot, DIRSEP, CVSROOTADM_MODULES);
  50.     if ((db = dbm_open(mfile, O_RDONLY, 0666)) == NULL)
  51.     warn(0, "warning: cannot open modules file %s", mfile);
  52.     return (db);
  53. }
  54.  
  55. /*
  56.  * Close the modules file, if the open succeeded, that is
  57.  */
  58. close_module(db)
  59.     DBM *db;
  60. {
  61.     if (db != NULL) {
  62.     dbm_close(db);
  63.     }
  64. }
  65.  
  66. /*
  67.  * This is the recursive function that processes a module name.
  68.  * If tag is set, just tag files, otherwise, we were called to check files
  69.  * out.
  70.  */
  71. do_module(db, mname, m_type, msg)
  72.     DBM *db;
  73.     char *mname;
  74.     enum mtype m_type;
  75.     char *msg;
  76. {
  77.     char *checkin_prog = NULL, *checkout_prog = NULL, *tag_prog = NULL;
  78.     char cwd[MAXPATHLEN], file[MAXPATHLEN], value[MAXPATHLEN];
  79.     char *moduleargv[MAXFILEPERDIR];
  80.     int moduleargc, just_file;
  81.     datum key, val;
  82.     char *cp, **argv;
  83.     int c, alias = 0, argc, err = 0;
  84.  
  85.     just_file = FALSE;
  86.     update_build_dirs = FALSE;
  87.     /*
  88.      * Look the argument module name up in the database; if we found it, use
  89.      * it, otherwise, see if the file or directory exists relative to the
  90.      * root directory (CVSroot).  If there is a directory there, it is
  91.      * extracted or tagged recursively; if there is a file there, it is
  92.      * extracted or tagged individually; if there is no file or directory
  93.      * there, we are done.
  94.      */
  95.     key.dptr = mname;
  96.     key.dsize = strlen(key.dptr);
  97.     if (db != NULL)
  98.     val = dbm_fetch(db, key);
  99.     else
  100.     val.dptr = NULL;
  101.     if (val.dptr != NULL) {
  102.         strncpy(value, val.dptr, val.dsize);
  103.     value[val.dsize] = '\0';
  104.     } else {
  105.     /*
  106.      * Need to determine if the argument module name is a directory
  107.      * or a file relative to the CVS root and set update_build_dirs
  108.      * and just_file accordingly
  109.      */
  110.     update_build_dirs = TRUE;
  111.     (void) sprintf(file, "%s%c%s", CVSroot, DIRSEP, key.dptr);
  112.     if (!isdir(file)) {
  113.         (void) strcat(file, RCSEXT);
  114.         if (!isfile(file)) {
  115.         warn(0, "cannot find '%s' - ignored", key.dptr);
  116.         err++;
  117.         return (err);
  118.         } else {
  119.         update_build_dirs = FALSE;
  120.         just_file = TRUE;
  121.         }
  122.     }
  123.     val = key;
  124.     }
  125.     /*
  126.      * If just extracting or tagging files, need to munge the
  127.      * passed in module name to look like an actual module entry.
  128.      */
  129.     if (just_file == TRUE) {
  130.     if ((cp = rindex_sep(key.dptr)) != NULL) {
  131.         *cp++ = '\0';
  132.     } else {
  133.         cp = key.dptr;
  134.         key.dptr = ".";
  135.     }
  136.     (void) sprintf(file, "%s %s %s", key.dptr, key.dptr, cp);
  137.     } else {
  138.     (void) sprintf(file, "%s %s", key.dptr, value);
  139.     }
  140.     line2argv(&moduleargc, moduleargv, file);
  141.     argc = moduleargc;
  142.     argv = moduleargv;
  143.     if (getwd(cwd) == NULL)
  144.     error(0, "cannot get current working directory: %s", cwd);
  145.     optind = 1;
  146.     while ((c = getopt(argc, argv, CVSMODULE_OPTS)) != -1) {
  147.     switch (c) {
  148.     case 'a':
  149.         alias = 1;
  150.         break;
  151.     case 'i':
  152.         checkin_prog = optarg;
  153.         break;
  154.     case 'o':
  155.         checkout_prog = optarg;
  156.         break;
  157.     case 't':
  158.         tag_prog = optarg;
  159.         break;
  160.     case '?':
  161.         warn(0, "modules file has invalid option for key %s value %s",
  162.          key.dptr, value);
  163.         err++;
  164.         return (err);
  165.         break;
  166.     }
  167.     }
  168.     argc -= optind;
  169.     argv += optind;
  170.     if (argc == 0) {
  171.     warn(0, "modules file missing directory for key %s value %s",
  172.          key.dptr, value);
  173.     err++;
  174.     return (err);
  175.     }
  176.     if (alias) {
  177.     register int i;
  178.  
  179.     for (i = 0; i < argc; i++) {
  180.         if (!quiet)
  181.         printf("%s %s: %s %s\n", progname, command, msg, argv[i]);
  182.         err += do_module(db, argv[i], m_type, msg);
  183.     }
  184.     return (err);
  185.     }
  186.     err += process_module(argc, argv, m_type, &key);
  187.     if (err == 0 && run_module_prog) {
  188.     if (m_type == CHECKOUT && checkin_prog !=  NULL) {
  189.         FILE *fp = open_file(CVSADM_CIPROG, "w+");
  190.         (void) fprintf(fp, "%s\n", checkin_prog);
  191.         (void) fclose(fp);
  192.     }
  193.     }
  194.     if (chdir(cwd) < 0)
  195.     error(1, "failed chdir to %s!", cwd);
  196.     if (err == 0 && run_module_prog) {
  197.     if ((m_type == TAG && tag_prog != NULL) ||
  198.         (m_type == CHECKOUT && checkout_prog != NULL)) {
  199.         (void) sprintf(prog, "%s %s",
  200.                m_type == TAG ? tag_prog : checkout_prog, key.dptr);
  201.         if (!quiet)
  202.         printf("%s %s: Executing '%s'\n", progname, command, prog);
  203.         err += system(prog);
  204.     }
  205.     }
  206.     free_names(&moduleargc, moduleargv);
  207.     return (err);
  208. }
  209.  
  210. static
  211. process_module(argc, argv, m_type, keyp)
  212.     int argc;
  213.     char *argv[];
  214.     enum mtype m_type;
  215.     datum *keyp;
  216. {
  217.     register int i, just_file;
  218.     int err = 0;
  219.  
  220.     just_file = argc > 1;
  221.     if (!just_file && update_build_dirs == FALSE && argc == 1)
  222.     update_build_dirs = TRUE;
  223.     if (m_type == TAG || m_type == PATCH) {
  224.     (void) sprintf(Repository, "%s%c%s", CVSroot, DIRSEP, argv[0]);
  225.     if (chdir(Repository) < 0) {
  226.         warn(1, "cannot chdir to %s", Repository);
  227.         err++;
  228.         return (err);
  229.     }
  230.     } else {
  231.     if (Build_Dirs_and_chdir(keyp->dptr) != 0) {
  232.         warn(0, "ignoring module %s", keyp->dptr);
  233.         err++;
  234.         return (err);
  235.     }
  236.     (void) sprintf(Repository, "%s%c%s", CVSroot, DIRSEP, argv[0]);
  237.     if (!isdir(CVSADM)) {
  238.         FILE *fp;
  239.  
  240.         Create_Admin(Repository, DFLT_RECORD);
  241.         if (just_file == TRUE) {
  242.         fp = open_file(CVSADM_ENTSTAT, "w+");
  243.         (void) fclose(fp);
  244.         }
  245.     } else {
  246.         char file[MAXPATHLEN];
  247.  
  248.         (void) strcpy(file, Repository);
  249.         Name_Repository();
  250.         if (strcmp(Repository, file) != 0) {
  251.         warn(0, "existing repository %s does not match %s",
  252.              Repository, file);
  253.         err++;
  254.         return (err);
  255.         }
  256.     }
  257.     }
  258.     if (update_build_dirs == TRUE) {
  259.     extern char update_dir[];
  260.  
  261.     (void) strcpy(update_dir, keyp->dptr);
  262.     if (m_type == CHECKOUT)
  263.         err += update(0, (char **)0);
  264.     else if (m_type == TAG)
  265.         err += tagit((char *)0);
  266.     else if (m_type == PATCH)
  267.         err += patched((char *)0);
  268.     else
  269.         error(0, "impossible module type %d", (int)m_type);
  270.     update_dir[0] = '\0';
  271.     return (err);
  272.     }
  273.     argc--;
  274.     argv++;
  275.     for (i = 0; i < argc; i++) {
  276.     char line[MAXLINELEN];
  277.  
  278.     (void) strcpy(User, argv[i]);
  279.     (void) sprintf(Rcs, "%s%c%s%s", Repository, DIRSEP, User, RCSEXT);
  280.     if (m_type == CHECKOUT) {
  281.         Version_TS(Rcs, Tag, User);
  282.         if (TS_User[0] == '\0') {
  283.         (void) sprintf(line, "Initial %s", User);
  284.         Register(User, VN_Rcs, line);
  285.         }
  286.     } else if (m_type == TAG) {
  287.         err += tagit(Rcs);
  288.     } else if (m_type == PATCH) {
  289.         err += patched(Rcs);
  290.     } else {
  291.         error(0, "impossible module type %d", (int)m_type);
  292.     }
  293.     }
  294.     if (m_type == CHECKOUT)
  295.     err += update(++argc, --argv);
  296.     return (err);
  297. }
  298.  
  299. cat_module()
  300. {
  301.     FILE *fp;
  302.     DBM *db;
  303.     datum key, val;
  304.     char value[MAXPATHLEN];
  305.  
  306.     if ((db = open_module()) == NULL)
  307.     error(0, "failed to cat the modules file");
  308.     if ((fp = popen(SORT, "w")) == NULL)
  309.     fp = stdout;
  310.     for (key = dbm_firstkey(db); key.dptr != NULL; key = dbm_nextkey(db)) {
  311.     key.dptr[key.dsize] = '\0';
  312.     (void) fprintf(fp, "%-20s", key.dptr);
  313.     val = dbm_fetch(db, key);
  314.     if (val.dptr != NULL) {
  315.             strncpy(value, val.dptr, val.dsize);
  316.         value[val.dsize] = '\0';
  317.         (void) fprintf(fp, " %s\n", value);
  318.     } else {
  319.         (void) fprintf(fp, "\n");
  320.     }
  321.     }
  322.     if (fp != stdout)
  323.     (void) pclose(fp);
  324. }
  325.