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

Diff for /src/usr.bin/cvs/status.c between version 1.56 and 1.57

version 1.56, 2006/04/14 02:45:35 version 1.57, 2006/05/27 03:30:31
Line 1 
Line 1 
 /*      $OpenBSD$       */  /*      $OpenBSD$       */
 /*  /*
  * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>   * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
  * Copyright (c) 2005 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 "includes.h"
Line 31 
Line 21 
 #include "log.h"  #include "log.h"
 #include "proto.h"  #include "proto.h"
   
   int     cvs_status(int, char **);
   void    cvs_status_local(struct cvs_file *);
   
 #define CVS_STATUS_SEP \  
  "==================================================================="  
   
 /* Keep this sorted as it is now. See file.h for status values. */  
 const char *cvs_statstr[] = {  
         "Unknown",  
         "Up-to-date",  
         "Locally Modified",  
         "Locally Added",  
         "Locally Removed",  
         "Unresolved Conflict",  
         "Patched",  
         "Needs Checkout",  
 };  
   
   
 static int cvs_status_init     (struct cvs_cmd *, int, char **, int *);  
 static int cvs_status_remote   (CVSFILE *, void *);  
 static int cvs_status_local    (CVSFILE *, void *);  
 static int cvs_status_pre_exec (struct cvsroot *);  
   
 struct cvs_cmd cvs_cmd_status = {  struct cvs_cmd cvs_cmd_status = {
         CVS_OP_STATUS, CVS_REQ_STATUS, "status",          CVS_OP_STATUS, CVS_REQ_STATUS, "status",
         { "st", "stat" },          { "st", "stat" },
         "Display status information on checked out files",          "Display status information on checked out files",
         "[-lRv]",          "[-lRv]",
         "lRv",          "lRv:",
         NULL,          NULL,
         CF_SORT | CF_IGNORE | CF_RECURSE,          cvs_status
         cvs_status_init,  
         cvs_status_pre_exec,  
         cvs_status_remote,  
         cvs_status_local,  
         NULL,  
         NULL,  
         CVS_CMD_ALLOWSPEC | CVS_CMD_SENDDIR | CVS_CMD_SENDARGS2  
 };  };
   
 static int verbose = 0;  #define CVS_STATUS_SEP  \
           "==================================================================="
   
 static int  const char *status_tab[] = {
 cvs_status_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)          "Unknown",
           "Locally Added",
           "Locally Removed",
           "Locally Modified",
           "Up-to-date",
           "Needs Checkout",
           "Needs Checkout",
           "Needs Merge",
           "Needs Patch",
           "Entry Invalid",
           "Unresolved Conflict",
           "Classifying error",
   };
   
   int
   cvs_status(int argc, char **argv)
 {  {
         int ch;          int ch;
           char *arg = ".";
           struct cvs_recursion cr;
   
         while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {          while ((ch = getopt(argc, argv, cvs_cmd_status.cmd_opts)) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'l':                  case 'l':
                         cmd->file_flags &= ~CF_RECURSE;  
                         break;                          break;
                 case 'R':                  case 'R':
                         cmd->file_flags |= CF_RECURSE;  
                         break;                          break;
                 case 'v':                  case 'v':
                         verbose = 1;  
                         break;                          break;
                 default:                  default:
                         return (CVS_EX_USAGE);                          fatal("%s", cvs_cmd_status.cmd_synopsis);
                 }                  }
         }          }
   
         *arg = optind;          argc -= optind;
         return (0);          argv += optind;
 }  
   
 static int          cr.enterdir = NULL;
 cvs_status_pre_exec(struct cvsroot *root)          cr.leavedir = NULL;
 {          cr.local = cvs_status_local;
         if (root->cr_method != CVS_METHOD_LOCAL) {          cr.remote = NULL;
                 if (verbose == 1)  
                         cvs_sendarg(root, "-v", 0);  
         }  
   
           if (argc > 0)
                   cvs_file_run(argc, argv, &cr);
           else
                   cvs_file_run(1, &arg, &cr);
   
         return (0);          return (0);
 }  }
   
 /*  void
  * cvs_status_remote()  cvs_status_local(struct cvs_file *cf)
  *  
  * Get the status of a single file.  
  */  
 static int  
 cvs_status_remote(CVSFILE *cfp, void *arg)  
 {  {
         char fpath[MAXPATHLEN];          int l;
         struct cvsroot *root;          size_t len;
           const char *status;
           char buf[128], timebuf[32], revbuf[32];
   
         root = CVS_DIR_ROOT(cfp);          cvs_log(LP_TRACE, "cvs_status_local(%s)", cf->file_path);
   
         if (cfp->cf_type == DT_DIR) {          cvs_file_classify(cf);
                 if (cfp->cf_cvstat == CVS_FST_UNKNOWN)  
                         cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name);  
                 else  
                         cvs_senddir(root, cfp);  
                 return (0);  
         }  
   
         cvs_file_getpath(cfp, fpath, sizeof(fpath));          if (cf->file_type == CVS_DIR) {
   
         cvs_sendentry(root, cfp);  
   
         switch (cfp->cf_cvstat) {  
         case CVS_FST_UNKNOWN:  
                 cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name);  
                 break;  
         case CVS_FST_UPTODATE:  
                 cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name);  
                 break;  
         case CVS_FST_ADDED:  
         case CVS_FST_MODIFIED:  
                 cvs_sendreq(root, CVS_REQ_MODIFIED, cfp->cf_name);  
                 cvs_sendfile(root, fpath);  
                 break;  
         default:  
                 break;  
         }  
   
         return (0);  
 }  
   
 static int  
 cvs_status_local(CVSFILE *cf, void *arg)  
 {  
         size_t n;  
         char buf[MAXNAMLEN], fpath[MAXPATHLEN], rcspath[MAXPATHLEN];  
         char numbuf[64], timebuf[32];  
         RCSFILE *rf;  
         struct rcs_sym *sym;  
   
         if (cf->cf_type == DT_DIR) {  
                 if (verbosity > 1)                  if (verbosity > 1)
                         cvs_log(LP_NOTICE, "Examining %s", cf->cf_name);                          cvs_log(LP_NOTICE, "Examining %s", cf->file_path);
                 return (0);                  return;
         }          }
   
         cvs_file_getpath(cf, fpath, sizeof(fpath));          cvs_printf("%s\n", CVS_STATUS_SEP);
         cvs_rcs_getpath(cf, rcspath, sizeof(rcspath));  
   
         rf = NULL;          status = status_tab[cf->file_status];
         if (cf->cf_cvstat != CVS_FST_UNKNOWN &&          if (cf->file_status == FILE_MODIFIED &&
             cf->cf_cvstat != CVS_FST_ADDED) {              cf->file_ent->ce_conflict != NULL)
                 if ((rf = rcs_open(rcspath, RCS_READ)) == NULL)                  status = "File had conflicts on merge";
                         fatal("cvs_status_local: rcs_open `%s': %s", rcspath,  
                             rcs_errstr(rcs_errno));  
         }  
   
         buf[0] = '\0';          cvs_printf("File: %-17s\tStatus: %s\n\n", cf->file_name, status);
   
         if (cf->cf_cvstat == CVS_FST_UNKNOWN)          if (cf->file_ent == NULL) {
                 cvs_log(LP_WARN, "nothing known about %s", cf->cf_name);                  l = snprintf(buf, sizeof(buf),
                       "No entry for %s", cf->file_name);
         if (cf->cf_cvstat == CVS_FST_LOST || cf->cf_cvstat == CVS_FST_UNKNOWN)                  if (l == -1 || l >= (int)sizeof(buf))
                 strlcpy(buf, "no file ", sizeof(buf));                          fatal("cvs_status_local: overflow");
         strlcat(buf, cf->cf_name, sizeof(buf));          } else if (cf->file_status == FILE_ADDED) {
                   len = strlcpy(buf, "New file!", sizeof(buf));
         cvs_printf(CVS_STATUS_SEP "\nFile: %-17s\tStatus: %s\n\n",                  if (len >= sizeof(buf))
             buf, cvs_statstr[cf->cf_cvstat]);                          fatal("cvs_status_local: truncation");
   
         if (cf->cf_cvstat == CVS_FST_UNKNOWN) {  
                 strlcpy(buf, "No entry for ", sizeof(buf));  
                 strlcat(buf, cf->cf_name, sizeof(buf));  
         } else if (cf->cf_cvstat == CVS_FST_ADDED) {  
                 strlcpy(buf, "New file!", sizeof(buf));  
         } else {          } else {
                 rcsnum_tostr(cf->cf_lrev, numbuf, sizeof(numbuf));                  rcsnum_tostr(cf->file_ent->ce_rev, revbuf, sizeof(revbuf));
                 strlcpy(buf, numbuf, sizeof(buf));  
   
                 /* Display etime in local mode only. */                  if (cf->file_ent->ce_conflict == NULL) {
                 if (cvs_cmdop != CVS_OP_SERVER) {                          ctime_r(&(cf->file_ent->ce_mtime), timebuf);
                         strlcat(buf, "\t", sizeof(buf));                          if (timebuf[strlen(timebuf) - 1] == '\n')
                                   timebuf[strlen(timebuf) - 1] = '\0';
                         ctime_r(&(cf->cf_etime), timebuf);                  } else {
                         n = strlen(timebuf);                          len = strlcpy(timebuf, cf->file_ent->ce_conflict,
                         if (n > 0 && timebuf[n - 1] == '\n')                              sizeof(timebuf));
                                 timebuf[--n] = '\0';                          if (len >= sizeof(timebuf))
                                   fatal("cvs_status_local: truncation");
                         strlcat(buf, timebuf, sizeof(buf));  
                 }                  }
   
                   l = snprintf(buf, sizeof(buf), "%s\t%s", revbuf, timebuf);
                   if (l == -1 || l >= (int)sizeof(buf))
                           fatal("cvs_status_local: overflow");
         }          }
   
         cvs_printf("   Working revision:\t%s\n", buf);          cvs_printf("   Working revision:\t%s\n", buf);
   
         if (cf->cf_cvstat == CVS_FST_UNKNOWN ||          buf[0] = '\0';
             cf->cf_cvstat == CVS_FST_ADDED) {          if (cf->file_rcs == NULL) {
                 strlcpy(buf, "No revision control file", sizeof(buf));                  len = strlcat(buf, "No revision control file", sizeof(buf));
                   if (len >= sizeof(buf))
                           fatal("cvs_status_local: truncation");
         } else {          } else {
                 strlcpy(buf, rcsnum_tostr(rf->rf_head, numbuf, sizeof(numbuf)),                  rcsnum_tostr(cf->file_rcs->rf_head, revbuf, sizeof(revbuf));
                     sizeof(buf));                  l = snprintf(buf, sizeof(buf), "%s\t%s", revbuf,
                 strlcat(buf, "\t", sizeof(buf));                      cf->file_rpath);
                 strlcat(buf, rcspath, sizeof(buf));                  if (l == -1 || l >= (int)sizeof(buf))
                           fatal("cvs_status_local: overflow");
         }          }
   
         cvs_printf("   Repository revision:\t%s\n", buf);          cvs_printf("   Repository revision:\t%s\n", buf);
   
         /* If the file is unknown, no other output is needed after this. */          if (cf->file_ent != NULL) {
         if (cf->cf_cvstat == CVS_FST_UNKNOWN) {                  if (cf->file_ent->ce_tag != NULL)
                 cvs_printf("\n");                          cvs_printf("   Sticky Tag:\t%s\n",
                 return (0);                              cf->file_ent->ce_tag);
                   if (cf->file_ent->ce_opts != NULL)
                           cvs_printf("   Sticky Options:\t%s\n",
                               cf->file_ent->ce_opts);
         }          }
   
         if (cf->cf_tag != NULL)  
                 cvs_printf("   Sticky Tag:\t\t%s\n", cf->cf_tag);  
         else if (verbosity > 0)  
                 cvs_printf("   Sticky Tag:\t\t(none)\n");  
   
         /* XXX */  
         if (verbosity > 0)  
                 cvs_printf("   Sticky Date:\t\t%s\n", "(none)");  
   
         if (cf->cf_opts != NULL)  
                 cvs_printf("   Sticky Options:\t%s\n", cf->cf_opts);  
         else if (verbosity > 0)  
                 cvs_printf("   Sticky Options:\t(none)\n");  
   
         if (verbose == 1) {  
                 cvs_printf("\n");  
                 cvs_printf("   Existing Tags:\n");  
   
                 if (!TAILQ_EMPTY(&(rf->rf_symbols))) {  
                         TAILQ_FOREACH(sym, &(rf->rf_symbols), rs_list) {  
                                 rcsnum_tostr(sym->rs_num, numbuf,  
                                     sizeof(numbuf));  
   
                                 cvs_printf("\t%-25s\t(%s: %s)\n",  
                                     sym->rs_name,  
                                     RCSNUM_ISBRANCH(sym->rs_num) ? "branch" :  
                                     "revision", numbuf);  
                         }  
                 } else {  
                         cvs_printf("\tNo Tags Exist\n");  
                 }  
         }  
   
         cvs_printf("\n");          cvs_printf("\n");
   
         if (rf != NULL)  
                 rcs_close(rf);  
   
         return (0);  
 }  }

Legend:
Removed from v.1.56  
changed lines
  Added in v.1.57