home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / rcs / sources / add.c next >
C/C++ Source or Header  |  1992-02-23  |  6KB  |  239 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Id: add.c,v 1.10 89/11/19 23:40:28 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.  * Add
  12.  *
  13.  *    Adds a file or directory to the RCS source repository.  For a file,
  14.  *    the entry is marked as "needing to be added" in the user's own
  15.  *    CVS.adm directory, and really added to the repository when it is
  16.  *    committed.  For a directory, it is added at the appropriate place
  17.  *    in the source repository and a CVS.adm directory is generated
  18.  *    within the directory.
  19.  *
  20.  *    The -m option is currently the only supported option.  Some may wish
  21.  *    to supply standard "rcs" options here, but I've found that this
  22.  *    causes more trouble than anything else.
  23.  *
  24.  *    The user files or directories must already exist.  For a directory,
  25.  *    it must not already have a CVS.adm file in it.
  26.  *
  27.  *    An "add" on a file that has been "remove"d but not committed will
  28.  *    cause the file to be resurrected.
  29.  */
  30.  
  31. #include "cvs.h"
  32.  
  33. add(argc, argv)
  34.     int argc;
  35.     char *argv[];
  36. {
  37.     char tmp[MAXPATHLEN], message[MAXMESGLEN];
  38.     register int i;
  39.     int c, err = 0;
  40.  
  41.     if (argc == 1 || argc == -1)
  42.     add_usage();
  43.     message[0] = '\0';
  44.     optind = 1;
  45.     while ((c = getopt(argc, argv, "m:")) != -1) {
  46.     switch (c) {
  47.     case 'm':
  48.         if (strlen(optarg) >= sizeof(message)) {
  49.         warn(0, "warning: message too long; truncated!");
  50.         (void) strncpy(message, optarg, sizeof(message));
  51.         message[sizeof(message) - 1] = '\0';
  52.         } else
  53.         (void) strcpy(message, optarg);
  54.         break;
  55.     case '?':
  56.     default:
  57.         add_usage();
  58.         break;
  59.     }
  60.     }
  61.     argc -= optind;
  62.     argv += optind;
  63.     Name_Repository();
  64.     for (i = 0; i < argc; i++) {
  65.     (void) strcpy(User, argv[i]);
  66.     if (isdir(User)) {
  67.         err += add_directory(User);
  68.         continue;
  69.     }
  70.     (void) sprintf(Rcs, "%s%c%s%s", Repository, DIRSEP, User, RCSEXT);
  71.     Version_TS(Rcs, Tag, User);
  72.     if (VN_User[0] == '\0') {
  73.         /*
  74.          * No entry available, TS_Rcs is invalid
  75.          */
  76.         if (VN_Rcs[0] == '\0') {
  77.         /*
  78.          * There is no RCS file either
  79.          */
  80.         if (TS_User[0] == '\0') {
  81.             /*
  82.              * There is no user file either
  83.              */
  84.             warn(0, "nothing known about %s", User);
  85.             err++;
  86.         } else {
  87.             /*
  88.              * There is a user file, so build the entry for it
  89.              */
  90.             if (Build_Entry(message) != 0)
  91.             err++;
  92.         }
  93.         } else {
  94.         /*
  95.          * There is an RCS file already, so somebody else
  96.          * must've added it
  97.          */
  98.         warn(0, "%s added independently by second party", User);
  99.         err++;
  100.         }
  101.     } else if (VN_User[0] == '0' && VN_User[1] == '\0') {
  102.         /*
  103.          * An entry for a new-born file, TS_Rcs is dummy,
  104.          * but that is inappropriate here
  105.          */
  106.         warn(0, "%s has already been entered", User);
  107.         err++;
  108.     } else if (VN_User[0] == '-') {
  109.         /*
  110.          * An entry for a removed file, TS_Rcs is invalid
  111.          */
  112.         if (TS_User[0] == '\0') {
  113.         /*
  114.          * There is no user file (as it should be)
  115.          */
  116.         if (VN_Rcs[0] == '\0') {
  117.             /*
  118.              * There is no RCS file, so somebody else must've
  119.              * removed it from under us
  120.              */
  121.             warn(0, "cannot resurrect %s; RCS file removed by second party",
  122.              User);
  123.             err++;
  124.         } else {
  125.             /*
  126.              * There is an RCS file, so remove the "-" from the
  127.              * version number and restore the file
  128.              */
  129.             (void) strcpy(tmp, VN_User+1);
  130.             (void) strcpy(VN_User, tmp);
  131.             (void) sprintf(tmp, "Resurrected %s", User);
  132.             Register(User, VN_User, tmp);
  133.             if (update(2, argv+i-1) == 0) {
  134.             warn(0, "%s, version %s, resurrected", User, VN_User);
  135.             } else {
  136.             warn(0, "could not resurrect %s", User);
  137.             err++;
  138.             }
  139.         }
  140.         } else {
  141.         /*
  142.          * The user file shouldn't be there
  143.          */
  144.         warn(0, "%s should be removed and is still there", User);
  145.         err++;
  146.         }
  147.     } else {
  148.         /*
  149.          * A normal entry, TS_Rcs is valid, so it must already be there
  150.          */
  151.         warn(0, "%s already exists, with version number %s", User, VN_User);
  152.         err++;
  153.     }
  154.     }
  155.     Entries2Files();            /* update CVS.adm/Files file */
  156.     exit(err);
  157. }
  158.  
  159. /*
  160.  * The specified user file is really a directory.  So, let's make sure that
  161.  * it is created in the RCS source repository, and that the user's
  162.  * directory is updated to include a CVS.adm directory.
  163.  *
  164.  * Returns 1 on failure, 0 on success.
  165.  */
  166. static
  167. add_directory(dir)
  168.     char *dir;
  169. {
  170.     char cwd[MAXPATHLEN], rcsdir[MAXPATHLEN];
  171.     char message[MAXPATHLEN+100];
  172.  
  173.     if (index_sep(dir) != NULL) {
  174.     warn(0, "directory %s not added; must be a direct sub-directory", dir);
  175.     return (1);
  176.     }
  177.     if (stricmp(dir, CVSADM) == 0) {
  178.     warn(0, "cannot add a '%s' directory", CVSADM);
  179.     return (1);
  180.     }
  181.     if (getwd(cwd) == NULL) {
  182.     warn(0, "cannot get working directory: %s", cwd);
  183.     return (1);
  184.     }
  185.     if (chdir(dir) < 0) {
  186.     warn(1, "cannot chdir to %s", dir);
  187.     return (1);
  188.     }
  189.     if (isfile(CVSADM)) {
  190.     warn(0, "%s%c%s already exists", dir, DIRSEP, CVSADM);
  191.     goto out;
  192.     }
  193.     (void) sprintf(rcsdir, "%s%c%s", Repository, DIRSEP, dir);
  194.     if (isfile(rcsdir) && !isdir(rcsdir)) {
  195.     warn(0, "%s is not a directory; %s not added", rcsdir, dir);
  196.     goto out;
  197.     }
  198.     (void) sprintf(message, "Directory %s added to the repository\n", rcsdir);
  199.     if (!isdir(rcsdir)) {
  200.     int omask;
  201.     FILE *fptty;
  202.     char line[MAXLINELEN];
  203.  
  204.     fptty = open_file(CONSOLE, "r");
  205.     printf("Add directory %s to the repository (y/n) [n] ? ", rcsdir);
  206.     (void) fflush(stdout);
  207.     if (fgets(line, sizeof(line), fptty) == NULL ||
  208.         (line[0] != 'y' && line[0] != 'Y')) {
  209.         warn(0, "directory %s not added", rcsdir);
  210.         (void) fclose(fptty);
  211.         goto out;
  212.     }
  213.     (void) fclose(fptty);
  214.     omask = umask(2);
  215.     if (mkdir(rcsdir, 0777) < 0) {
  216.         warn(1, "cannot mkdir %s", rcsdir);
  217.         (void) umask(omask);
  218.         goto out;
  219.     }
  220.     (void) umask(omask);
  221.     (void) strcpy(Llist, " - New directory"); /* for title in message */
  222.     Update_Logfile(rcsdir, message);
  223.     }
  224.     Create_Admin(rcsdir, DFLT_RECORD);
  225.     printf("%s", message);
  226. out:
  227.     if (chdir(cwd) < 0)
  228.     error(1, "cannot chdir to %s", cwd);
  229.     return (0);
  230. }
  231.  
  232. static
  233. add_usage()
  234. {
  235.     (void) fprintf(stderr,
  236.            "%s %s [-m 'message'] files...\n", progname, command);
  237.     exit(1);
  238. }
  239.