Annotation of src/usr.bin/cvs/status.c, Revision 1.66
1.66 ! joris 1: /* $OpenBSD: status.c,v 1.65 2006/06/16 14:07:42 joris Exp $ */
1.1 jfb 2: /*
1.57 joris 3: * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
1.64 xsa 4: * Copyright (c) 2005, 2006 Xavier Santolaria <xsa@openbsd.org>
1.1 jfb 5: *
1.57 joris 6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
1.1 jfb 9: *
1.57 joris 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 jfb 17: */
18:
1.51 xsa 19: #include "includes.h"
1.1 jfb 20:
21: #include "cvs.h"
22: #include "log.h"
23:
1.57 joris 24: int cvs_status(int, char **);
25: void cvs_status_local(struct cvs_file *);
1.22 jfb 26:
1.64 xsa 27: static int show_sym = 0;
28:
1.22 jfb 29: struct cvs_cmd cvs_cmd_status = {
1.65 joris 30: CVS_OP_STATUS, 0, "status",
1.22 jfb 31: { "st", "stat" },
32: "Display status information on checked out files",
33: "[-lRv]",
1.64 xsa 34: "lRv",
1.22 jfb 35: NULL,
1.57 joris 36: cvs_status
1.10 joris 37: };
1.1 jfb 38:
1.57 joris 39: #define CVS_STATUS_SEP \
40: "==================================================================="
1.1 jfb 41:
1.57 joris 42: const char *status_tab[] = {
43: "Unknown",
44: "Locally Added",
45: "Locally Removed",
46: "Locally Modified",
47: "Up-to-date",
48: "Needs Checkout",
49: "Needs Checkout",
50: "Needs Merge",
51: "Needs Patch",
52: "Entry Invalid",
53: "Unresolved Conflict",
54: "Classifying error",
55: };
56:
57: int
58: cvs_status(int argc, char **argv)
1.1 jfb 59: {
1.58 joris 60: int ch, flags;
1.57 joris 61: char *arg = ".";
62: struct cvs_recursion cr;
1.1 jfb 63:
1.58 joris 64: flags = CR_REPO | CR_RECURSE_DIRS;
65:
1.57 joris 66: while ((ch = getopt(argc, argv, cvs_cmd_status.cmd_opts)) != -1) {
1.1 jfb 67: switch (ch) {
1.7 jfb 68: case 'l':
1.58 joris 69: flags &= ~CR_RECURSE_DIRS;
1.7 jfb 70: break;
71: case 'R':
72: break;
73: case 'v':
1.64 xsa 74: show_sym = 1;
1.7 jfb 75: break;
1.1 jfb 76: default:
1.57 joris 77: fatal("%s", cvs_cmd_status.cmd_synopsis);
1.1 jfb 78: }
79: }
80:
1.57 joris 81: argc -= optind;
82: argv += optind;
1.1 jfb 83:
1.57 joris 84: cr.enterdir = NULL;
85: cr.leavedir = NULL;
1.66 ! joris 86: cr.fileproc = cvs_status_local;
1.58 joris 87: cr.flags = flags;
1.57 joris 88:
89: if (argc > 0)
90: cvs_file_run(argc, argv, &cr);
91: else
92: cvs_file_run(1, &arg, &cr);
1.26 xsa 93:
1.1 jfb 94: return (0);
95: }
96:
1.57 joris 97: void
98: cvs_status_local(struct cvs_file *cf)
1.1 jfb 99: {
1.57 joris 100: int l;
101: size_t len;
102: const char *status;
103: char buf[128], timebuf[32], revbuf[32];
1.64 xsa 104: struct rcs_sym *sym;
1.1 jfb 105:
1.57 joris 106: cvs_log(LP_TRACE, "cvs_status_local(%s)", cf->file_path);
1.1 jfb 107:
1.61 joris 108: cvs_file_classify(cf, NULL, 1);
1.15 jfb 109:
1.57 joris 110: if (cf->file_type == CVS_DIR) {
1.33 xsa 111: if (verbosity > 1)
1.57 joris 112: cvs_log(LP_NOTICE, "Examining %s", cf->file_path);
113: return;
1.33 xsa 114: }
1.15 jfb 115:
1.57 joris 116: cvs_printf("%s\n", CVS_STATUS_SEP);
1.5 jfb 117:
1.57 joris 118: status = status_tab[cf->file_status];
119: if (cf->file_status == FILE_MODIFIED &&
120: cf->file_ent->ce_conflict != NULL)
121: status = "File had conflicts on merge";
122:
1.63 xsa 123: if (cf->file_status == FILE_LOST ||
124: cf->file_status == FILE_UNKNOWN ||
125: cf->file_rcs->rf_inattic == 1) {
126: l = snprintf(buf, sizeof(buf), "no file %s\t", cf->file_name);
127: if (l == -1 || l >= (int)sizeof(buf))
128: fatal("cvs_status_local: overflow");
129: } else
130: if (strlcpy(buf, cf->file_name, sizeof(buf)) >= sizeof(buf))
131: fatal("cvs_status_local: overflow");
132:
133: cvs_printf("File: %-17s\tStatus: %s\n\n", buf, status);
1.57 joris 134:
135: if (cf->file_ent == NULL) {
136: l = snprintf(buf, sizeof(buf),
137: "No entry for %s", cf->file_name);
138: if (l == -1 || l >= (int)sizeof(buf))
139: fatal("cvs_status_local: overflow");
140: } else if (cf->file_status == FILE_ADDED) {
141: len = strlcpy(buf, "New file!", sizeof(buf));
142: if (len >= sizeof(buf))
143: fatal("cvs_status_local: truncation");
1.16 jfb 144: } else {
1.57 joris 145: rcsnum_tostr(cf->file_ent->ce_rev, revbuf, sizeof(revbuf));
1.35 xsa 146:
1.57 joris 147: if (cf->file_ent->ce_conflict == NULL) {
148: ctime_r(&(cf->file_ent->ce_mtime), timebuf);
149: if (timebuf[strlen(timebuf) - 1] == '\n')
150: timebuf[strlen(timebuf) - 1] = '\0';
151: } else {
152: len = strlcpy(timebuf, cf->file_ent->ce_conflict,
153: sizeof(timebuf));
154: if (len >= sizeof(timebuf))
155: fatal("cvs_status_local: truncation");
156: }
1.35 xsa 157:
1.57 joris 158: l = snprintf(buf, sizeof(buf), "%s\t%s", revbuf, timebuf);
159: if (l == -1 || l >= (int)sizeof(buf))
160: fatal("cvs_status_local: overflow");
1.16 jfb 161: }
1.32 joris 162:
1.28 xsa 163: cvs_printf(" Working revision:\t%s\n", buf);
1.30 xsa 164:
1.57 joris 165: buf[0] = '\0';
166: if (cf->file_rcs == NULL) {
167: len = strlcat(buf, "No revision control file", sizeof(buf));
168: if (len >= sizeof(buf))
169: fatal("cvs_status_local: truncation");
1.30 xsa 170: } else {
1.62 joris 171: rcsnum_tostr(rcs_head_get(cf->file_rcs),
172: revbuf, sizeof(revbuf));
1.57 joris 173: l = snprintf(buf, sizeof(buf), "%s\t%s", revbuf,
174: cf->file_rpath);
175: if (l == -1 || l >= (int)sizeof(buf))
176: fatal("cvs_status_local: overflow");
1.30 xsa 177: }
178:
179: cvs_printf(" Repository revision:\t%s\n", buf);
180:
1.57 joris 181: if (cf->file_ent != NULL) {
182: if (cf->file_ent->ce_tag != NULL)
1.60 xsa 183: cvs_printf(" Sticky Tag:\t\t%s\n",
1.57 joris 184: cf->file_ent->ce_tag);
1.60 xsa 185: else if (verbosity > 0)
186: cvs_printf(" Sticky Tag:\t\t(none)\n");
187:
1.57 joris 188: if (cf->file_ent->ce_opts != NULL)
189: cvs_printf(" Sticky Options:\t%s\n",
190: cf->file_ent->ce_opts);
1.60 xsa 191: else if (verbosity > 0)
192: cvs_printf(" Sticky Options:\t(none)\n");
1.64 xsa 193: }
194:
195: if (show_sym == 1) {
196: cvs_printf("\n");
197: cvs_printf(" Existing Tags:\n");
198:
199: if (!TAILQ_EMPTY(&(cf->file_rcs->rf_symbols))) {
200: TAILQ_FOREACH(sym,
201: &(cf->file_rcs->rf_symbols), rs_list) {
202: (void)rcsnum_tostr(sym->rs_num, revbuf,
203: sizeof(revbuf));
204:
205: cvs_printf("\t%-25s\t(%s: %s)\n", sym->rs_name,
206: RCSNUM_ISBRANCH(sym->rs_num) ? "branch" :
207: "revision", revbuf);
208: }
209: } else
210: cvs_printf("\tNo Tags Exist\n");
1.41 xsa 211: }
1.15 jfb 212:
1.25 xsa 213: cvs_printf("\n");
1.1 jfb 214: }