Annotation of src/usr.bin/cvs/status.c, Revision 1.86
1.86 ! joris 1: /* $OpenBSD: status.c,v 1.85 2008/06/08 16:20:49 joris Exp $ */
1.1 jfb 2: /*
1.57 joris 3: * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
1.81 xsa 4: * Copyright (c) 2005-2008 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.73 otto 19: #include <string.h>
20: #include <unistd.h>
1.1 jfb 21:
22: #include "cvs.h"
1.68 joris 23: #include "remote.h"
1.1 jfb 24:
1.57 joris 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.80 tobias 30: CVS_OP_STATUS, CVS_USE_WDIR, "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.68 joris 64: flags = CR_RECURSE_DIRS;
1.58 joris 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':
1.79 tobias 72: flags |= CR_RECURSE_DIRS;
1.7 jfb 73: break;
74: case 'v':
1.64 xsa 75: show_sym = 1;
1.7 jfb 76: break;
1.1 jfb 77: default:
1.57 joris 78: fatal("%s", cvs_cmd_status.cmd_synopsis);
1.1 jfb 79: }
80: }
81:
1.57 joris 82: argc -= optind;
83: argv += optind;
1.1 jfb 84:
1.57 joris 85: cr.enterdir = NULL;
86: cr.leavedir = NULL;
1.68 joris 87:
88: if (current_cvsroot->cr_method == CVS_METHOD_LOCAL) {
89: flags |= CR_REPO;
90: cr.fileproc = cvs_status_local;
91: } else {
1.69 joris 92: cvs_client_connect_to_server();
1.68 joris 93: if (!(flags & CR_RECURSE_DIRS))
94: cvs_client_send_request("Argument -l");
95: if (show_sym)
96: cvs_client_send_request("Argument -v");
97: cr.fileproc = cvs_client_sendfile;
98: }
99:
1.58 joris 100: cr.flags = flags;
1.57 joris 101:
102: if (argc > 0)
103: cvs_file_run(argc, argv, &cr);
104: else
105: cvs_file_run(1, &arg, &cr);
1.68 joris 106:
107: if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
108: cvs_client_send_files(argv, argc);
109: cvs_client_senddir(".");
110: cvs_client_send_request("status");
111: cvs_client_get_responses();
112: }
1.26 xsa 113:
1.1 jfb 114: return (0);
115: }
116:
1.57 joris 117: void
118: cvs_status_local(struct cvs_file *cf)
1.1 jfb 119: {
1.57 joris 120: size_t len;
1.70 joris 121: RCSNUM *head;
1.57 joris 122: const char *status;
1.75 xsa 123: char buf[128], timebuf[CVS_TIME_BUFSZ], revbuf[CVS_REV_BUFSZ];
1.64 xsa 124: struct rcs_sym *sym;
1.1 jfb 125:
1.57 joris 126: cvs_log(LP_TRACE, "cvs_status_local(%s)", cf->file_path);
1.1 jfb 127:
1.77 joris 128: cvs_file_classify(cf, cvs_directory_tag);
1.15 jfb 129:
1.57 joris 130: if (cf->file_type == CVS_DIR) {
1.33 xsa 131: if (verbosity > 1)
1.57 joris 132: cvs_log(LP_NOTICE, "Examining %s", cf->file_path);
133: return;
1.33 xsa 134: }
1.15 jfb 135:
1.83 joris 136: if (cf->file_rcs != NULL) {
137: head = rcs_head_get(cf->file_rcs);
138: if (head == NULL && cf->file_status != FILE_REMOVE_ENTRY)
139: return;
140: } else {
141: head = NULL;
142: }
1.78 tobias 143:
1.57 joris 144: cvs_printf("%s\n", CVS_STATUS_SEP);
1.5 jfb 145:
1.57 joris 146: status = status_tab[cf->file_status];
147: if (cf->file_status == FILE_MODIFIED &&
148: cf->file_ent->ce_conflict != NULL)
149: status = "File had conflicts on merge";
150:
1.63 xsa 151: if (cf->file_status == FILE_LOST ||
1.78 tobias 152: cf->file_status == FILE_REMOVE_ENTRY ||
1.77 joris 153: (cf->file_rcs != NULL && cf->in_attic == 1 && cf->fd == -1)) {
1.71 xsa 154: (void)xsnprintf(buf, sizeof(buf), "no file %s\t",
155: cf->file_name);
1.63 xsa 156: } else
157: if (strlcpy(buf, cf->file_name, sizeof(buf)) >= sizeof(buf))
158: fatal("cvs_status_local: overflow");
159:
160: cvs_printf("File: %-17s\tStatus: %s\n\n", buf, status);
1.57 joris 161:
162: if (cf->file_ent == NULL) {
1.71 xsa 163: (void)xsnprintf(buf, sizeof(buf),
1.57 joris 164: "No entry for %s", cf->file_name);
1.78 tobias 165: } else if (cf->file_status == FILE_ADDED ||
166: cf->file_status == FILE_REMOVE_ENTRY) {
1.57 joris 167: len = strlcpy(buf, "New file!", sizeof(buf));
168: if (len >= sizeof(buf))
169: fatal("cvs_status_local: truncation");
1.16 jfb 170: } else {
1.57 joris 171: rcsnum_tostr(cf->file_ent->ce_rev, revbuf, sizeof(revbuf));
1.35 xsa 172:
1.57 joris 173: if (cf->file_ent->ce_conflict == NULL) {
174: ctime_r(&(cf->file_ent->ce_mtime), timebuf);
175: if (timebuf[strlen(timebuf) - 1] == '\n')
176: timebuf[strlen(timebuf) - 1] = '\0';
177: } else {
178: len = strlcpy(timebuf, cf->file_ent->ce_conflict,
179: sizeof(timebuf));
180: if (len >= sizeof(timebuf))
181: fatal("cvs_status_local: truncation");
182: }
1.35 xsa 183:
1.76 xsa 184: (void)strlcpy(buf, revbuf, sizeof(buf));
185: if (cvs_server_active == 0) {
186: (void)strlcat(buf, "\t", sizeof(buf));
187: (void)strlcat(buf, timebuf, sizeof(buf));
188: }
1.16 jfb 189: }
1.32 joris 190:
1.28 xsa 191: cvs_printf(" Working revision:\t%s\n", buf);
1.30 xsa 192:
1.57 joris 193: buf[0] = '\0';
1.78 tobias 194: if (cf->file_rcs == NULL || head == NULL) {
1.57 joris 195: len = strlcat(buf, "No revision control file", sizeof(buf));
196: if (len >= sizeof(buf))
197: fatal("cvs_status_local: truncation");
1.30 xsa 198: } else {
1.70 joris 199: rcsnum_tostr(head, revbuf, sizeof(revbuf));
200: rcsnum_free(head);
1.71 xsa 201: (void)xsnprintf(buf, sizeof(buf), "%s\t%s", revbuf,
1.57 joris 202: cf->file_rpath);
1.30 xsa 203: }
204:
205: cvs_printf(" Repository revision:\t%s\n", buf);
206:
1.57 joris 207: if (cf->file_ent != NULL) {
208: if (cf->file_ent->ce_tag != NULL)
1.60 xsa 209: cvs_printf(" Sticky Tag:\t\t%s\n",
1.57 joris 210: cf->file_ent->ce_tag);
1.60 xsa 211: else if (verbosity > 0)
212: cvs_printf(" Sticky Tag:\t\t(none)\n");
1.81 xsa 213:
214: if (cf->file_ent->ce_date != -1) {
215: struct tm *datetm;
216: char datetmp[CVS_TIME_BUFSZ];
217:
218: datetm = gmtime(&(cf->file_ent->ce_date));
219: (void)strftime(datetmp, sizeof(datetmp),
1.82 xsa 220: CVS_DATE_FMT, datetm);
1.81 xsa 221:
222: cvs_printf(" Sticky Date:\t\t%s\n", datetmp);
223: } else if (verbosity > 0)
224: cvs_printf(" Sticky Date:\t\t(none)\n");
1.60 xsa 225:
1.57 joris 226: if (cf->file_ent->ce_opts != NULL)
227: cvs_printf(" Sticky Options:\t%s\n",
228: cf->file_ent->ce_opts);
1.60 xsa 229: else if (verbosity > 0)
230: cvs_printf(" Sticky Options:\t(none)\n");
1.64 xsa 231: }
232:
1.86 ! joris 233: if (cf->file_rcs != NULL && show_sym == 1) {
1.64 xsa 234: cvs_printf("\n");
235: cvs_printf(" Existing Tags:\n");
236:
237: if (!TAILQ_EMPTY(&(cf->file_rcs->rf_symbols))) {
238: TAILQ_FOREACH(sym,
239: &(cf->file_rcs->rf_symbols), rs_list) {
240: (void)rcsnum_tostr(sym->rs_num, revbuf,
241: sizeof(revbuf));
242:
243: cvs_printf("\t%-25s\t(%s: %s)\n", sym->rs_name,
244: RCSNUM_ISBRANCH(sym->rs_num) ? "branch" :
245: "revision", revbuf);
246: }
247: } else
248: cvs_printf("\tNo Tags Exist\n");
1.41 xsa 249: }
1.15 jfb 250:
1.25 xsa 251: cvs_printf("\n");
1.1 jfb 252: }