=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/status.c,v retrieving revision 1.56 retrieving revision 1.57 diff -c -r1.56 -r1.57 *** src/usr.bin/cvs/status.c 2006/04/14 02:45:35 1.56 --- src/usr.bin/cvs/status.c 2006/05/27 03:30:31 1.57 *************** *** 1,28 **** ! /* $OpenBSD: status.c,v 1.56 2006/04/14 02:45:35 deraadt Exp $ */ /* ! * Copyright (c) 2004 Jean-Francois Brousseau ! * Copyright (c) 2005 Xavier Santolaria ! * All rights reserved. * ! * Redistribution and use in source and binary forms, with or without ! * modification, are permitted provided that the following conditions ! * are met: * ! * 1. Redistributions of source code must retain the above copyright ! * notice, this list of conditions and the following disclaimer. ! * 2. The name of the author may not be used to endorse or promote products ! * derived from this software without specific prior written permission. ! * ! * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, ! * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY ! * 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" --- 1,18 ---- ! /* $OpenBSD: status.c,v 1.57 2006/05/27 03:30:31 joris Exp $ */ /* ! * Copyright (c) 2006 Joris Vink * ! * Permission to use, copy, modify, and distribute this software for any ! * purpose with or without fee is hereby granted, provided that the above ! * copyright notice and this permission notice appear in all copies. * ! * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ! * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ! * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ! * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ! * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ! * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ! * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "includes.h" *************** *** 31,274 **** #include "log.h" #include "proto.h" - #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 = { CVS_OP_STATUS, CVS_REQ_STATUS, "status", { "st", "stat" }, "Display status information on checked out files", "[-lRv]", ! "lRv", NULL, ! CF_SORT | CF_IGNORE | CF_RECURSE, ! 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; ! static int ! cvs_status_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg) { int ch; ! while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) { switch (ch) { case 'l': - cmd->file_flags &= ~CF_RECURSE; break; case 'R': - cmd->file_flags |= CF_RECURSE; break; case 'v': - verbose = 1; break; default: ! return (CVS_EX_USAGE); } } ! *arg = optind; ! return (0); ! } ! static int ! cvs_status_pre_exec(struct cvsroot *root) ! { ! if (root->cr_method != CVS_METHOD_LOCAL) { ! if (verbose == 1) ! cvs_sendarg(root, "-v", 0); ! } return (0); } ! /* ! * cvs_status_remote() ! * ! * Get the status of a single file. ! */ ! static int ! cvs_status_remote(CVSFILE *cfp, void *arg) { ! char fpath[MAXPATHLEN]; ! struct cvsroot *root; ! root = CVS_DIR_ROOT(cfp); ! if (cfp->cf_type == DT_DIR) { ! 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)); ! ! 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) ! cvs_log(LP_NOTICE, "Examining %s", cf->cf_name); ! return (0); } ! cvs_file_getpath(cf, fpath, sizeof(fpath)); ! cvs_rcs_getpath(cf, rcspath, sizeof(rcspath)); ! rf = NULL; ! if (cf->cf_cvstat != CVS_FST_UNKNOWN && ! cf->cf_cvstat != CVS_FST_ADDED) { ! if ((rf = rcs_open(rcspath, RCS_READ)) == NULL) ! fatal("cvs_status_local: rcs_open `%s': %s", rcspath, ! rcs_errstr(rcs_errno)); ! } ! buf[0] = '\0'; ! if (cf->cf_cvstat == CVS_FST_UNKNOWN) ! cvs_log(LP_WARN, "nothing known about %s", cf->cf_name); ! ! if (cf->cf_cvstat == CVS_FST_LOST || cf->cf_cvstat == CVS_FST_UNKNOWN) ! strlcpy(buf, "no file ", sizeof(buf)); ! strlcat(buf, cf->cf_name, sizeof(buf)); ! ! cvs_printf(CVS_STATUS_SEP "\nFile: %-17s\tStatus: %s\n\n", ! buf, cvs_statstr[cf->cf_cvstat]); ! ! 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 { ! rcsnum_tostr(cf->cf_lrev, numbuf, sizeof(numbuf)); ! strlcpy(buf, numbuf, sizeof(buf)); ! /* Display etime in local mode only. */ ! if (cvs_cmdop != CVS_OP_SERVER) { ! strlcat(buf, "\t", sizeof(buf)); ! ! ctime_r(&(cf->cf_etime), timebuf); ! n = strlen(timebuf); ! if (n > 0 && timebuf[n - 1] == '\n') ! timebuf[--n] = '\0'; ! ! strlcat(buf, timebuf, sizeof(buf)); } } cvs_printf(" Working revision:\t%s\n", buf); ! if (cf->cf_cvstat == CVS_FST_UNKNOWN || ! cf->cf_cvstat == CVS_FST_ADDED) { ! strlcpy(buf, "No revision control file", sizeof(buf)); } else { ! strlcpy(buf, rcsnum_tostr(rf->rf_head, numbuf, sizeof(numbuf)), ! sizeof(buf)); ! strlcat(buf, "\t", sizeof(buf)); ! strlcat(buf, rcspath, sizeof(buf)); } cvs_printf(" Repository revision:\t%s\n", buf); ! /* If the file is unknown, no other output is needed after this. */ ! if (cf->cf_cvstat == CVS_FST_UNKNOWN) { ! cvs_printf("\n"); ! return (0); } - 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"); - - if (rf != NULL) - rcs_close(rf); - - return (0); } --- 21,173 ---- #include "log.h" #include "proto.h" + int cvs_status(int, char **); + void cvs_status_local(struct cvs_file *); struct cvs_cmd cvs_cmd_status = { CVS_OP_STATUS, CVS_REQ_STATUS, "status", { "st", "stat" }, "Display status information on checked out files", "[-lRv]", ! "lRv:", NULL, ! cvs_status }; ! #define CVS_STATUS_SEP \ ! "===================================================================" ! const char *status_tab[] = { ! "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; + char *arg = "."; + struct cvs_recursion cr; ! while ((ch = getopt(argc, argv, cvs_cmd_status.cmd_opts)) != -1) { switch (ch) { case 'l': break; case 'R': break; case 'v': break; default: ! fatal("%s", cvs_cmd_status.cmd_synopsis); } } ! argc -= optind; ! argv += optind; ! cr.enterdir = NULL; ! cr.leavedir = NULL; ! cr.local = cvs_status_local; ! cr.remote = NULL; + if (argc > 0) + cvs_file_run(argc, argv, &cr); + else + cvs_file_run(1, &arg, &cr); + return (0); } ! void ! cvs_status_local(struct cvs_file *cf) { ! int l; ! size_t len; ! const char *status; ! char buf[128], timebuf[32], revbuf[32]; ! cvs_log(LP_TRACE, "cvs_status_local(%s)", cf->file_path); ! cvs_file_classify(cf); ! if (cf->file_type == CVS_DIR) { if (verbosity > 1) ! cvs_log(LP_NOTICE, "Examining %s", cf->file_path); ! return; } ! cvs_printf("%s\n", CVS_STATUS_SEP); ! status = status_tab[cf->file_status]; ! if (cf->file_status == FILE_MODIFIED && ! cf->file_ent->ce_conflict != NULL) ! status = "File had conflicts on merge"; ! cvs_printf("File: %-17s\tStatus: %s\n\n", cf->file_name, status); ! if (cf->file_ent == NULL) { ! l = snprintf(buf, sizeof(buf), ! "No entry for %s", cf->file_name); ! if (l == -1 || l >= (int)sizeof(buf)) ! fatal("cvs_status_local: overflow"); ! } else if (cf->file_status == FILE_ADDED) { ! len = strlcpy(buf, "New file!", sizeof(buf)); ! if (len >= sizeof(buf)) ! fatal("cvs_status_local: truncation"); } else { ! rcsnum_tostr(cf->file_ent->ce_rev, revbuf, sizeof(revbuf)); ! if (cf->file_ent->ce_conflict == NULL) { ! ctime_r(&(cf->file_ent->ce_mtime), timebuf); ! if (timebuf[strlen(timebuf) - 1] == '\n') ! timebuf[strlen(timebuf) - 1] = '\0'; ! } else { ! len = strlcpy(timebuf, cf->file_ent->ce_conflict, ! sizeof(timebuf)); ! if (len >= sizeof(timebuf)) ! fatal("cvs_status_local: truncation"); } + + 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); ! buf[0] = '\0'; ! if (cf->file_rcs == NULL) { ! len = strlcat(buf, "No revision control file", sizeof(buf)); ! if (len >= sizeof(buf)) ! fatal("cvs_status_local: truncation"); } else { ! rcsnum_tostr(cf->file_rcs->rf_head, revbuf, sizeof(revbuf)); ! l = snprintf(buf, sizeof(buf), "%s\t%s", revbuf, ! cf->file_rpath); ! if (l == -1 || l >= (int)sizeof(buf)) ! fatal("cvs_status_local: overflow"); } cvs_printf(" Repository revision:\t%s\n", buf); ! if (cf->file_ent != NULL) { ! if (cf->file_ent->ce_tag != NULL) ! cvs_printf(" Sticky Tag:\t%s\n", ! cf->file_ent->ce_tag); ! if (cf->file_ent->ce_opts != NULL) ! cvs_printf(" Sticky Options:\t%s\n", ! cf->file_ent->ce_opts); } cvs_printf("\n"); }