kernel: Remove the FFS_ROOT option. It was a no-op since 4.9.
[dragonfly.git] / contrib / cvs-1.12 / src / status.c
blob11ab5acbf83063fe94fea0133ad45f041feef557
1 /*
2 * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
4 * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
5 * and others.
7 * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
8 * Portions Copyright (C) 1989-1992, Brian Berliner
9 *
10 * You may distribute under the terms of the GNU General Public License as
11 * specified in the README file that comes with the CVS source distribution.
13 * Status Information
16 #include "cvs.h"
18 static Dtype status_dirproc (void *callerdat, const char *dir,
19 const char *repos, const char *update_dir,
20 List *entries);
21 static int status_fileproc (void *callerdat, struct file_info *finfo);
22 static int tag_list_proc (Node * p, void *closure);
24 static int local = 0;
25 static int long_format = 0;
26 static RCSNode *xrcsnode;
28 static const char *const status_usage[] =
30 "Usage: %s %s [-vlR] [files...]\n",
31 "\t-v\tVerbose format; includes tag information for the file\n",
32 "\t-l\tProcess this directory only (not recursive).\n",
33 "\t-R\tProcess directories recursively.\n",
34 "(Specify the --help global option for a list of other help options)\n",
35 NULL
38 int
39 cvsstatus (int argc, char **argv)
41 int c;
42 int err = 0;
44 if (argc == -1)
45 usage (status_usage);
47 optind = 0;
48 while ((c = getopt (argc, argv, "+vlR")) != -1)
50 switch (c)
52 case 'v':
53 long_format = 1;
54 break;
55 case 'l':
56 local = 1;
57 break;
58 case 'R':
59 local = 0;
60 break;
61 case '?':
62 default:
63 usage (status_usage);
64 break;
67 argc -= optind;
68 argv += optind;
70 wrap_setup ();
72 #ifdef CLIENT_SUPPORT
73 if (current_parsed_root->isremote)
75 start_server ();
77 ign_setup ();
79 if (long_format)
80 send_arg("-v");
81 if (local)
82 send_arg("-l");
83 send_arg ("--");
85 /* For a while, we tried setting SEND_NO_CONTENTS here so this
86 could be a fast operation. That prevents the
87 server from updating our timestamp if the timestamp is
88 changed but the file is unmodified. Worse, it is user-visible
89 (shows "locally modified" instead of "up to date" if
90 timestamp is changed but file is not). And there is no good
91 workaround (you might not want to run "cvs update"; "cvs -n
92 update" doesn't update CVS/Entries; "cvs diff --brief" or
93 something perhaps could be made to work but somehow that
94 seems nonintuitive to me even if so). Given that timestamps
95 seem to have the potential to get munged for any number of
96 reasons, it seems better to not rely too much on them. */
98 send_files (argc, argv, local, 0, 0);
100 send_file_names (argc, argv, SEND_EXPAND_WILD);
102 send_to_server ("status\012", 0);
103 err = get_responses_and_close ();
105 return err;
107 #endif
109 /* start the recursion processor */
110 err = start_recursion (status_fileproc, NULL, status_dirproc,
111 NULL, NULL, argc, argv, local, W_LOCAL,
112 0, CVS_LOCK_READ, NULL, 1, NULL);
114 return (err);
118 * display the status of a file
120 /* ARGSUSED */
121 static int
122 status_fileproc (void *callerdat, struct file_info *finfo)
124 Ctype status;
125 char *sstat;
126 Vers_TS *vers;
127 Node *node;
129 status = Classify_File (finfo, NULL, NULL, NULL, 1, 0, &vers, 0);
130 sstat = "Classify Error";
131 switch (status)
133 case T_UNKNOWN:
134 sstat = "Unknown";
135 break;
136 case T_CHECKOUT:
137 sstat = "Needs Checkout";
138 break;
139 case T_PATCH:
140 sstat = "Needs Patch";
141 break;
142 case T_CONFLICT:
143 /* FIXME - This message could be clearer. It comes up
144 * when a file exists or has been added in the local sandbox
145 * and a file of the same name has been committed indepenently to
146 * the repository from a different sandbox, as well as when a
147 * timestamp hasn't changed since a merge resulted in conflicts.
148 * It also comes up whether an update has been attempted or not, so
149 * technically, I think the double-add case is not actually a
150 * conflict yet.
152 sstat = "Unresolved Conflict";
153 break;
154 case T_ADDED:
155 sstat = "Locally Added";
156 break;
157 case T_REMOVED:
158 sstat = "Locally Removed";
159 break;
160 case T_MODIFIED:
161 if (file_has_markers (finfo))
162 sstat = "File had conflicts on merge";
163 else
164 /* Note that we do not re Register() the file when we spot
165 * a resolved conflict like update_fileproc() does on the
166 * premise that status should not alter the sandbox.
168 sstat = "Locally Modified";
169 break;
170 case T_REMOVE_ENTRY:
171 sstat = "Entry Invalid";
172 break;
173 case T_UPTODATE:
174 sstat = "Up-to-date";
175 break;
176 case T_NEEDS_MERGE:
177 sstat = "Needs Merge";
178 break;
179 case T_TITLE:
180 /* I don't think this case can occur here. Just print
181 "Classify Error". */
182 break;
185 cvs_output ("\
186 ===================================================================\n", 0);
187 if (vers->ts_user == NULL)
189 cvs_output ("File: no file ", 0);
190 cvs_output (finfo->file, 0);
191 cvs_output ("\t\tStatus: ", 0);
192 cvs_output (sstat, 0);
193 cvs_output ("\n\n", 0);
195 else
197 char *buf;
198 buf = Xasprintf ("File: %-17s\tStatus: %s\n\n", finfo->file, sstat);
199 cvs_output (buf, 0);
200 free (buf);
203 if (vers->vn_user == NULL)
205 cvs_output (" Working revision:\tNo entry for ", 0);
206 cvs_output (finfo->file, 0);
207 cvs_output ("\n", 0);
209 else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
210 cvs_output (" Working revision:\tNew file!\n", 0);
211 else
213 cvs_output (" Working revision:\t", 0);
214 cvs_output (vers->vn_user, 0);
216 /* Only add the UTC timezone if there is a time to use. */
217 if (!server_active && strlen (vers->ts_rcs) > 0)
219 /* Convert from the asctime() format to ISO 8601 */
220 char *buf;
222 cvs_output ("\t", 0);
224 /* Allow conversion from CVS/Entries asctime() to ISO 8601 */
225 buf = Xasprintf ("%s UTC", vers->ts_rcs);
226 cvs_output_tagged ("date", buf);
227 free (buf);
229 cvs_output ("\n", 0);
232 if (vers->vn_rcs == NULL)
233 cvs_output (" Repository revision:\tNo revision control file\n", 0);
234 else
236 cvs_output (" Repository revision:\t", 0);
237 cvs_output (vers->vn_rcs, 0);
238 cvs_output ("\t", 0);
239 cvs_output (vers->srcfile->print_path, 0);
240 cvs_output ("\n", 0);
242 node = findnode(vers->srcfile->versions,vers->vn_rcs);
243 if (node)
245 RCSVers *v;
246 v=(RCSVers*)node->data;
247 node = findnode(v->other_delta,"commitid");
248 cvs_output(" Commit Identifier:\t", 0);
249 if(node && node->data)
250 cvs_output(node->data, 0);
251 else
252 cvs_output("(none)",0);
253 cvs_output("\n",0);
257 if (vers->entdata)
259 Entnode *edata;
261 edata = vers->entdata;
262 if (edata->tag)
264 if (vers->vn_rcs == NULL)
266 cvs_output (" Sticky Tag:\t\t", 0);
267 cvs_output (edata->tag, 0);
268 cvs_output (" - MISSING from RCS file!\n", 0);
270 else
272 if (isdigit ((unsigned char) edata->tag[0]))
274 cvs_output (" Sticky Tag:\t\t", 0);
275 cvs_output (edata->tag, 0);
276 cvs_output ("\n", 0);
278 else
280 char *branch = NULL;
282 if (RCS_nodeisbranch (finfo->rcs, edata->tag))
283 branch = RCS_whatbranch(finfo->rcs, edata->tag);
285 cvs_output (" Sticky Tag:\t\t", 0);
286 cvs_output (edata->tag, 0);
287 cvs_output (" (", 0);
288 cvs_output (branch ? "branch" : "revision", 0);
289 cvs_output (": ", 0);
290 cvs_output (branch ? branch : vers->vn_rcs, 0);
291 cvs_output (")\n", 0);
293 if (branch)
294 free (branch);
298 else if (!really_quiet)
299 cvs_output (" Sticky Tag:\t\t(none)\n", 0);
301 if (edata->date)
303 cvs_output (" Sticky Date:\t\t", 0);
304 cvs_output (edata->date, 0);
305 cvs_output ("\n", 0);
307 else if (!really_quiet)
308 cvs_output (" Sticky Date:\t\t(none)\n", 0);
310 if (edata->options && edata->options[0])
312 cvs_output (" Sticky Options:\t", 0);
313 cvs_output (edata->options, 0);
314 cvs_output ("\n", 0);
316 else if (!really_quiet)
317 cvs_output (" Sticky Options:\t(none)\n", 0);
320 if (long_format && vers->srcfile)
322 List *symbols = RCS_symbols(vers->srcfile);
324 cvs_output ("\n Existing Tags:\n", 0);
325 if (symbols)
327 xrcsnode = finfo->rcs;
328 (void) walklist (symbols, tag_list_proc, NULL);
330 else
331 cvs_output ("\tNo Tags Exist\n", 0);
334 cvs_output ("\n", 0);
335 freevers_ts (&vers);
336 return (0);
342 * Print a warm fuzzy message
344 /* ARGSUSED */
345 static Dtype
346 status_dirproc (void *callerdat, const char *dir, const char *repos,
347 const char *update_dir, List *entries)
349 if (!quiet)
350 error (0, 0, "Examining %s", update_dir);
351 return (R_PROCESS);
357 * Print out a tag and its type
359 static int
360 tag_list_proc (Node *p, void *closure)
362 char *branch = NULL;
363 char *buf;
365 if (RCS_nodeisbranch (xrcsnode, p->key))
366 branch = RCS_whatbranch(xrcsnode, p->key) ;
368 buf = Xasprintf ("\t%-25s\t(%s: %s)\n", p->key,
369 branch ? "branch" : "revision",
370 branch ? branch : (char *)p->data);
371 cvs_output (buf, 0);
372 free (buf);
374 if (branch)
375 free (branch);
377 return (0);