home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / cvs-1.8 / cvs-1 / cvs-1.8.1 / src / remove.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-06  |  4.7 KB  |  201 lines

  1. /*
  2.  * Copyright (c) 1992, Brian Berliner and Jeff Polk
  3.  * Copyright (c) 1989-1992, Brian Berliner
  4.  * 
  5.  * You may distribute under the terms of the GNU General Public License as
  6.  * specified in the README file that comes with the CVS 1.4 kit.
  7.  * 
  8.  * Remove a File
  9.  * 
  10.  * Removes entries from the present version. The entries will be removed from
  11.  * the RCS repository upon the next "commit".
  12.  * 
  13.  * "remove" accepts no options, only file names that are to be removed.  The
  14.  * file must not exist in the current directory for "remove" to work
  15.  * correctly.
  16.  */
  17.  
  18. #include "cvs.h"
  19.  
  20. static int remove_fileproc PROTO((struct file_info *finfo));
  21. static Dtype remove_dirproc PROTO((char *dir, char *repos, char *update_dir));
  22.  
  23. static int force;
  24. static int local;
  25. static int removed_files;
  26. static int existing_files;
  27.  
  28. static const char *const remove_usage[] =
  29. {
  30.     "Usage: %s %s [-flR] [files...]\n",
  31.     "\t-f\tDelete the file before removing it.\n",
  32.     "\t-l\tProcess this directory only (not recursive).\n",
  33.     "\t-R\tProcess directories recursively.\n",
  34.     NULL
  35. };
  36.  
  37. int
  38. cvsremove (argc, argv)
  39.     int argc;
  40.     char **argv;
  41. {
  42.     int c, err;
  43.  
  44.     if (argc == -1)
  45.     usage (remove_usage);
  46.  
  47.     optind = 1;
  48.     while ((c = getopt (argc, argv, "flR")) != -1)
  49.     {
  50.     switch (c)
  51.     {
  52.         case 'f':
  53.         force = 1;
  54.         break;
  55.         case 'l':
  56.         local = 1;
  57.         break;
  58.         case 'R':
  59.         local = 0;
  60.         break;
  61.         case '?':
  62.         default:
  63.         usage (remove_usage);
  64.         break;
  65.     }
  66.     }
  67.     argc -= optind;
  68.     argv += optind;
  69.  
  70.     wrap_setup ();
  71.  
  72. #ifdef CLIENT_SUPPORT
  73.     if (client_active) {
  74.     start_server ();
  75.     ign_setup ();
  76.     if (local)
  77.         send_arg("-l");
  78.     send_file_names (argc, argv, SEND_EXPAND_WILD);
  79.     send_files (argc, argv, local, 0);
  80.     send_to_server ("remove\012", 0);
  81.         return get_responses_and_close ();
  82.     }
  83. #endif
  84.  
  85.     /* start the recursion processor */
  86.     err = start_recursion (remove_fileproc, (FILESDONEPROC) NULL,
  87.                            remove_dirproc, (DIRLEAVEPROC) NULL, argc, argv,
  88.                            local, W_LOCAL, 0, 1, (char *) NULL, 1, 0);
  89.  
  90.     if (removed_files)
  91.     error (0, 0, "use '%s commit' to remove %s permanently", program_name,
  92.            (removed_files == 1) ? "this file" : "these files");
  93.  
  94.     if (existing_files)
  95.     error (0, 0,
  96.            ((existing_files == 1) ?
  97.         "%d file exists; remove it first" :
  98.         "%d files exist; remove them first"),
  99.            existing_files);
  100.  
  101.     return (err);
  102. }
  103.  
  104. /*
  105.  * remove the file, only if it has already been physically removed
  106.  */
  107. /* ARGSUSED */
  108. static int
  109. remove_fileproc (finfo)
  110.     struct file_info *finfo;
  111. {
  112.     char fname[PATH_MAX];
  113.     Vers_TS *vers;
  114.  
  115.     if (force)
  116.     {
  117.     if (!noexec)
  118.     {
  119.         if (unlink (finfo->file) < 0 && ! existence_error (errno))
  120.         {
  121.         error (0, errno, "unable to remove %s", finfo->fullname);
  122.         }
  123.     }
  124.     /* else FIXME should probably act as if the file doesn't exist
  125.        in doing the following checks.  */
  126.     }
  127.  
  128.     vers = Version_TS (finfo->repository, (char *) NULL, (char *) NULL, (char *) NULL,
  129.                finfo->file, 0, 0, finfo->entries, finfo->rcs);
  130.  
  131.     if (vers->ts_user != NULL)
  132.     {
  133.     existing_files++;
  134.     if (!quiet)
  135.         error (0, 0, "file `%s' still in working directory",
  136.            finfo->fullname);
  137.     }
  138.     else if (vers->vn_user == NULL)
  139.     {
  140.     if (!quiet)
  141.         error (0, 0, "nothing known about `%s'", finfo->fullname);
  142.     }
  143.     else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
  144.     {
  145.     /*
  146.      * It's a file that has been added, but not commited yet. So,
  147.      * remove the ,t file for it and scratch it from the
  148.      * entries file.  */
  149.     Scratch_Entry (finfo->entries, finfo->file);
  150.     (void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
  151.     (void) unlink_file (fname);
  152.     if (!quiet)
  153.         error (0, 0, "removed `%s'", finfo->fullname);
  154.  
  155. #ifdef SERVER_SUPPORT
  156.     if (server_active)
  157.         server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
  158. #endif
  159.     }
  160.     else if (vers->vn_user[0] == '-')
  161.     {
  162.     if (!quiet)
  163.         error (0, 0, "file `%s' already scheduled for removal",
  164.            finfo->fullname);
  165.     }
  166.     else
  167.     {
  168.     /* Re-register it with a negative version number.  */
  169.     (void) strcpy (fname, "-");
  170.     (void) strcat (fname, vers->vn_user);
  171.     Register (finfo->entries, finfo->file, fname, vers->ts_rcs, vers->options,
  172.           vers->tag, vers->date, vers->ts_conflict);
  173.     if (!quiet)
  174.         error (0, 0, "scheduling `%s' for removal", finfo->fullname);
  175.     removed_files++;
  176.  
  177. #ifdef SERVER_SUPPORT
  178.     if (server_active)
  179.         server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
  180. #endif
  181.     }
  182.  
  183.     freevers_ts (&vers);
  184.     return (0);
  185. }
  186.  
  187. /*
  188.  * Print a warm fuzzy message
  189.  */
  190. /* ARGSUSED */
  191. static Dtype
  192. remove_dirproc (dir, repos, update_dir)
  193.     char *dir;
  194.     char *repos;
  195.     char *update_dir;
  196. {
  197.     if (!quiet)
  198.     error (0, 0, "Removing %s", update_dir);
  199.     return (R_PROCESS);
  200. }
  201.