home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / cvs-1.8.7-src.tgz / tar.out / fsf / cvs / src / remove.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  5KB  |  229 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 ((void *callerdat, struct file_info *finfo));
  21. static Dtype remove_dirproc PROTO ((void *callerdat, char *dir,
  22.                     char *repos, char *update_dir,
  23.                     List *entries));
  24.  
  25. static int force;
  26. static int local;
  27. static int removed_files;
  28. static int existing_files;
  29.  
  30. static const char *const remove_usage[] =
  31. {
  32.     "Usage: %s %s [-flR] [files...]\n",
  33.     "\t-f\tDelete the file before removing it.\n",
  34.     "\t-l\tProcess this directory only (not recursive).\n",
  35.     "\t-R\tProcess directories recursively.\n",
  36.     NULL
  37. };
  38.  
  39. int
  40. cvsremove (argc, argv)
  41.     int argc;
  42.     char **argv;
  43. {
  44.     int c, err;
  45.  
  46.     if (argc == -1)
  47.     usage (remove_usage);
  48.  
  49.     optind = 1;
  50.     while ((c = getopt (argc, argv, "flR")) != -1)
  51.     {
  52.     switch (c)
  53.     {
  54.         case 'f':
  55.         force = 1;
  56.         break;
  57.         case 'l':
  58.         local = 1;
  59.         break;
  60.         case 'R':
  61.         local = 0;
  62.         break;
  63.         case '?':
  64.         default:
  65.         usage (remove_usage);
  66.         break;
  67.     }
  68.     }
  69.     argc -= optind;
  70.     argv += optind;
  71.  
  72.     wrap_setup ();
  73.  
  74. #ifdef CLIENT_SUPPORT
  75.     if (client_active) {
  76.     /* Call expand_wild so that the local removal of files will
  77.            work.  It's ok to do it always because we have to send the
  78.            file names expanded anyway.  */
  79.     expand_wild (argc, argv, &argc, &argv);
  80.     
  81.     if (force)
  82.     {
  83.         if (!noexec)
  84.         {
  85.         int i;
  86.  
  87.         for (i = 0; i < argc; i++)
  88.         {
  89.             if ( CVS_UNLINK (argv[i]) < 0 && ! existence_error (errno))
  90.             {
  91.             error (0, errno, "unable to remove %s", argv[i]);
  92.             }
  93.         }
  94.         }
  95.         /* else FIXME should probably act as if the file doesn't exist
  96.            in doing the following checks.  */
  97.     }
  98.  
  99.     start_server ();
  100.     ign_setup ();
  101.     if (local)
  102.         send_arg("-l");
  103.     send_file_names (argc, argv, 0);
  104.     send_files (argc, argv, local, 0);
  105.     send_to_server ("remove\012", 0);
  106.         return get_responses_and_close ();
  107.     }
  108. #endif
  109.  
  110.     /* start the recursion processor */
  111.     err = start_recursion (remove_fileproc, (FILESDONEPROC) NULL,
  112.                            remove_dirproc, (DIRLEAVEPROC) NULL, NULL,
  113.                argc, argv,
  114.                            local, W_LOCAL, 0, 1, (char *) NULL, 1);
  115.  
  116.     if (removed_files)
  117.     error (0, 0, "use '%s commit' to remove %s permanently", program_name,
  118.            (removed_files == 1) ? "this file" : "these files");
  119.  
  120.     if (existing_files)
  121.     error (0, 0,
  122.            ((existing_files == 1) ?
  123.         "%d file exists; remove it first" :
  124.         "%d files exist; remove them first"),
  125.            existing_files);
  126.  
  127.     return (err);
  128. }
  129.  
  130. /*
  131.  * remove the file, only if it has already been physically removed
  132.  */
  133. /* ARGSUSED */
  134. static int
  135. remove_fileproc (callerdat, finfo)
  136.     void *callerdat;
  137.     struct file_info *finfo;
  138. {
  139.     char fname[PATH_MAX];
  140.     Vers_TS *vers;
  141.  
  142.     if (force)
  143.     {
  144.     if (!noexec)
  145.     {
  146.         if ( CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
  147.         {
  148.         error (0, errno, "unable to remove %s", finfo->fullname);
  149.         }
  150.     }
  151.     /* else FIXME should probably act as if the file doesn't exist
  152.        in doing the following checks.  */
  153.     }
  154.  
  155.     vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
  156.  
  157.     if (vers->ts_user != NULL)
  158.     {
  159.     existing_files++;
  160.     if (!quiet)
  161.         error (0, 0, "file `%s' still in working directory",
  162.            finfo->fullname);
  163.     }
  164.     else if (vers->vn_user == NULL)
  165.     {
  166.     if (!quiet)
  167.         error (0, 0, "nothing known about `%s'", finfo->fullname);
  168.     }
  169.     else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
  170.     {
  171.     /*
  172.      * It's a file that has been added, but not commited yet. So,
  173.      * remove the ,t file for it and scratch it from the
  174.      * entries file.  */
  175.     Scratch_Entry (finfo->entries, finfo->file);
  176.     (void) sprintf (fname, "%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
  177.     (void) unlink_file (fname);
  178.     if (!quiet)
  179.         error (0, 0, "removed `%s'", finfo->fullname);
  180.  
  181. #ifdef SERVER_SUPPORT
  182.     if (server_active)
  183.         server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
  184. #endif
  185.     }
  186.     else if (vers->vn_user[0] == '-')
  187.     {
  188.     if (!quiet)
  189.         error (0, 0, "file `%s' already scheduled for removal",
  190.            finfo->fullname);
  191.     }
  192.     else
  193.     {
  194.     /* Re-register it with a negative version number.  */
  195.     (void) strcpy (fname, "-");
  196.     (void) strcat (fname, vers->vn_user);
  197.     Register (finfo->entries, finfo->file, fname, vers->ts_rcs, vers->options,
  198.           vers->tag, vers->date, vers->ts_conflict);
  199.     if (!quiet)
  200.         error (0, 0, "scheduling `%s' for removal", finfo->fullname);
  201.     removed_files++;
  202.  
  203. #ifdef SERVER_SUPPORT
  204.     if (server_active)
  205.         server_checked_in (finfo->file, finfo->update_dir, finfo->repository);
  206. #endif
  207.     }
  208.  
  209.     freevers_ts (&vers);
  210.     return (0);
  211. }
  212.  
  213. /*
  214.  * Print a warm fuzzy message
  215.  */
  216. /* ARGSUSED */
  217. static Dtype
  218. remove_dirproc (callerdat, dir, repos, update_dir, entries)
  219.     void *callerdat;
  220.     char *dir;
  221.     char *repos;
  222.     char *update_dir;
  223.     List *entries;
  224. {
  225.     if (!quiet)
  226.     error (0, 0, "Removing %s", update_dir);
  227.     return (R_PROCESS);
  228. }
  229.