[BACK]Return to release.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

Diff for /src/usr.bin/cvs/release.c between version 1.33 and 1.34

version 1.33, 2006/05/27 03:30:31 version 1.34, 2007/06/26 18:02:43
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*  /*-
  * Copyright (c) 2005 Xavier Santolaria <xsa@openbsd.org>   * Copyright (c) 2005-2007 Xavier Santolaria <xsa@openbsd.org>
  * All rights reserved.  
  *   *
  * Redistribution and use in source and binary forms, with or without   * Permission to use, copy, modify, and distribute this software for any
  * modification, are permitted provided that the following conditions   * purpose with or without fee is hereby granted, provided that the above
  * are met:   * copyright notice and this permission notice appear in all copies.
  *   *
  * 1. Redistributions of source code must retain the above copyright   * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  *    notice, this list of conditions and the following disclaimer.   * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * 2. The name of the author may not be used to endorse or promote products   * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  *    derived from this software without specific prior written permission.   * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  *   * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,   * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY   * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL  
  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  */   */
   
 #include "includes.h"  #include <sys/stat.h>
   
   #include <string.h>
   #include <unistd.h>
   
 #include "cvs.h"  #include "cvs.h"
 #include "log.h"  #include "remote.h"
 #include "proto.h"  
   
 #define UPDCMD_FLAGS    "-n -q -d"  
   
 extern char *__progname;  extern char *__progname;
   
 static int      cvs_release_init(struct cvs_cmd *, int, char **, int *);  void    cvs_release_local(struct cvs_file *);
 static int      cvs_release_pre_exec(struct cvsroot *);  
 static int      cvs_release_dir(CVSFILE *, void *);  
   
   static void     release_check_files(struct cvs_file *);
   
   static int      dflag = 0;
   static int      files_altered = 0;
   
 struct cvs_cmd cvs_cmd_release = {  struct cvs_cmd cvs_cmd_release = {
         CVS_OP_RELEASE, CVS_REQ_RELEASE, "release",          CVS_OP_RELEASE, 0, "release",
         { "re", "rel" },          { "re", "rel" },
         "Release",          "Indicate that a Module is no longer in use",
         "[-d]",          "[-d] dir...",
         "d",          "d",
         NULL,          NULL,
         CF_NOFILES,          cvs_release
         cvs_release_init,  
         cvs_release_pre_exec,  
         cvs_release_dir,  
         cvs_release_dir,  
         NULL,  
         NULL,  
         CVS_CMD_SENDDIR | CVS_CMD_SENDARGS2 | CVS_CMD_ALLOWSPEC  
 };  };
   
 static int      dflag;  /* -d option */  int
   cvs_release(int argc, char **argv)
 static int  
 cvs_release_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)  
 {  {
         int ch;          int ch;
           int flags;
           struct cvs_recursion cr;
   
         while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {          flags = CR_REPO;
   
           while ((ch = getopt(argc, argv, cvs_cmd_release.cmd_opts)) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'd':                  case 'd':
                         dflag = 1;                          dflag = 1;
                         break;                          break;
                 default:                  default:
                         return (CVS_EX_USAGE);                          fatal("%s", cvs_cmd_release.cmd_synopsis);
                 }                  }
         }          }
   
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
         *arg = optind;  
   
         if (argc == 0)          if (argc == 0)
                 return (CVS_EX_USAGE);                  fatal("%s", cvs_cmd_release.cmd_synopsis);
   
         return (0);          cr.enterdir = NULL;
 }          cr.leavedir = NULL;
   
 static int          if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
 cvs_release_pre_exec(struct cvsroot *root)                  cvs_client_connect_to_server();
 {                  cr.fileproc = cvs_client_sendfile;
         if (root->cr_method != CVS_METHOD_LOCAL) {  
                 if (dflag == 1)                  if (dflag == 1)
                         cvs_sendarg(root, "-d", 0);                          cvs_client_send_request("Argument -d");
           } else
                   cr.fileproc = cvs_release_local;
   
           cr.flags = flags;
   
           cvs_file_run(argc, argv, &cr);
   
           if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                   cvs_client_send_files(argv, argc);
                   cvs_client_senddir(".");
                   cvs_client_send_request("release");
                   cvs_client_get_responses();
         }          }
   
         return (0);          return (0);
 }  }
   
 /*  void
  * cvs_release_dir()  cvs_release_local(struct cvs_file *cf)
  *  
  * Release specified directorie(s).  
  * Returns 0 on success, or -1 on failure.  
  */  
 static int  
 cvs_release_dir(CVSFILE *cf, void *arg)  
 {  {
         FILE *fp;  
         int j, l;  
         char *wdir, cwd[MAXPATHLEN];  
         char buf[256], dpath[MAXPATHLEN], updcmd[1024];  
         struct stat st;          struct stat st;
         struct cvsroot *root;          struct cvs_recursion cr;
           char *wdir, cwd[MAXPATHLEN];
           char *arg = ".";
           int saved_noexec;
   
         j = 0;          if (cf->file_type == CVS_FILE)
                   return;
   
         root = CVS_DIR_ROOT(cf);          cvs_log(LP_TRACE, "cvs_release_local(%s)", cf->file_path);
   
         /* XXX kept for compat reason of `cvs update' output */          cvs_file_classify(cf, NULL);
         /* save current working directory for further use */  
           if (cvs_server_active == 1) {
                   cvs_history_add(CVS_HISTORY_RELEASE, cf, NULL);
                   return;
           }
   
         if ((wdir = getcwd(cwd, sizeof(cwd))) == NULL)          if ((wdir = getcwd(cwd, sizeof(cwd))) == NULL)
                 fatal("getcwd failed");                  fatal("getcwd failed");
   
         cvs_file_getpath(cf, dpath, sizeof(dpath));          if (cf->file_type == CVS_DIR) {
                   if (!strcmp(cf->file_name, "."))
                           return;
   
         if (cf->cf_type == DT_DIR) {                  /* chdir before updating the directory. */
                 if (!strcmp(cf->cf_name, "."))                  cvs_chdir(cf->file_path, 0);
                         return (0);  
   
                 /* chdir before running the `cvs update' command */                  if (stat(CVS_PATH_CVSDIR, &st) == -1 || !S_ISDIR(st.st_mode)) {
                 cvs_chdir(dpath, 0);                          cvs_log(LP_ERR, "no repository directory: %s",
                               cf->file_path);
                 /* test if dir has CVS/ directory */                          return;
                 if (stat(CVS_PATH_CVSDIR, &st) == -1) {  
                         if (verbosity > 0)  
                                 cvs_log(LP_ERR,  
                                     "no repository directory: %s", dpath);  
                         return (0);  
                 }                  }
         } else {  
                 if (verbosity > 0)  
                         cvs_log(LP_ERR, "no such directory: %s", dpath);  
                 return (0);  
         }          }
   
         /* construct `cvs update' command */          saved_noexec = cvs_noexec;
         l = snprintf(updcmd, sizeof(updcmd), "%s %s %s update",          cvs_noexec = 1;
             __progname, UPDCMD_FLAGS, root->cr_str);  
         if (l == -1 || l >= (int)sizeof(updcmd))  
                 fatal("cvs_release_dir: `cvs update' command string overflow");  
   
         /* XXX we should try to avoid a new connection ... */          cr.enterdir = NULL;
         cvs_log(LP_TRACE, "cvs_release_dir() popen(%s,r)", updcmd);          cr.leavedir = NULL;
         if ((fp = popen(updcmd, "r")) == NULL)          cr.fileproc = cvs_update_local;
                 fatal("cannot run command `%s'", updcmd);          cr.flags = CR_REPO | CR_RECURSE_DIRS;
   
         while (fgets(buf, (int)sizeof(buf), fp) != NULL) {          cvs_file_run(1, &arg, &cr);
                 if (strchr("ACMPRU", buf[0]))  
                         j++;  
                 (void)fputs(buf, stdout);  
         }  
   
         if (pclose(fp) != 0) {          cvs_noexec = saved_noexec;
                 cvs_log(LP_ERR, "unable to release `%s'", dpath);  
   
                 /* change back to original working dir */          cr.enterdir = NULL;
                 cvs_chdir(wdir, 0);          cr.leavedir = NULL;
         }          cr.fileproc = release_check_files;
           cr.flags = CR_RECURSE_DIRS;
   
         printf("You have [%d] altered file%s in this repository.\n",          cvs_file_run(1, &arg, &cr);
             j, j > 1 ? "s" : "");  
         while (fgets(buf, (int)sizeof(buf), fp) != NULL) {  
                 if (strchr("ACMPRU", buf[0]))  
                         j++;  
                 (void)fputs(buf, stdout);  
         }  
   
         printf("Are you sure you want to release %sdirectory `%s': ",          (void)printf("You have [%d] altered files in this repository.\n",
             dflag ? "(and delete) " : "", dpath);              files_altered);
           (void)printf("Are you sure you want to release %sdirectory `%s': ",
                   (dflag == 1) ? "(and delete) " : "", cf->file_path);
   
         if (cvs_yesno() == -1) {        /* No */          if (cvs_yesno() == -1) {
                 fprintf(stderr,                  (void)fprintf(stderr,
                     "** `%s' aborted by user choice.\n", cvs_command);                      "** `%s' aborted by user choice.\n", cvs_command);
   
                 /* change back to original working dir */                  /* change back to original working dir */
                 cvs_chdir(wdir, 0);                  cvs_chdir(wdir, 0);
   
                 return (-1);                  return;
         }          }
   
         /* change back to original working dir */          /* change back to original working dir */
         cvs_chdir(wdir, 0);          cvs_chdir(wdir, 0);
   
         if (dflag == 1) {          if (dflag == 1) {
                 if (cvs_rmdir(dpath) != 0)                  if (cvs_rmdir(cf->file_path) != 0)
                         fatal("cvs_release_dir: cvs_rmdir failed");                          fatal("cvs_release_local: cvs_rmdir failed");
         }          }
   }
   
         return (0);  static void
   release_check_files(struct cvs_file *cf)
   {
           cvs_log(LP_TRACE, "release_check_files(%s)", cf->file_path);
   
           cvs_file_classify(cf, NULL);
   
           if (cf->file_status == FILE_MERGE ||
               cf->file_status == FILE_ADDED ||
               cf->file_status == FILE_PATCH ||
               cf->file_status == FILE_CONFLICT)
                   files_altered++;
           return;
 }  }

Legend:
Removed from v.1.33  
changed lines
  Added in v.1.34