1*0d69c6cfSchristos /* $NetBSD: rcsdiff.c,v 1.2 2016/01/14 04:22:39 christos Exp $ */
2075184b7Schristos
3075184b7Schristos /* Compare RCS revisions. */
4075184b7Schristos
5075184b7Schristos /* Copyright 1982, 1988, 1989 Walter Tichy
6075184b7Schristos Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
7075184b7Schristos Distributed under license by the Free Software Foundation, Inc.
8075184b7Schristos
9075184b7Schristos This file is part of RCS.
10075184b7Schristos
11075184b7Schristos RCS is free software; you can redistribute it and/or modify
12075184b7Schristos it under the terms of the GNU General Public License as published by
13075184b7Schristos the Free Software Foundation; either version 2, or (at your option)
14075184b7Schristos any later version.
15075184b7Schristos
16075184b7Schristos RCS is distributed in the hope that it will be useful,
17075184b7Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
18075184b7Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19075184b7Schristos GNU General Public License for more details.
20075184b7Schristos
21075184b7Schristos You should have received a copy of the GNU General Public License
22075184b7Schristos along with RCS; see the file COPYING.
23075184b7Schristos If not, write to the Free Software Foundation,
24075184b7Schristos 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25075184b7Schristos
26075184b7Schristos Report problems and direct all questions to:
27075184b7Schristos
28075184b7Schristos rcs-bugs@cs.purdue.edu
29075184b7Schristos
30075184b7Schristos */
31075184b7Schristos
32075184b7Schristos /*
33075184b7Schristos * Log: rcsdiff.c,v
34075184b7Schristos * Revision 5.19 1995/06/16 06:19:24 eggert
35075184b7Schristos * Update FSF address.
36075184b7Schristos *
37075184b7Schristos * Revision 5.18 1995/06/01 16:23:43 eggert
38075184b7Schristos * (main): Pass "--binary" if -kb and if --binary makes a difference.
39075184b7Schristos * Don't treat + options specially.
40075184b7Schristos *
41075184b7Schristos * Revision 5.17 1994/03/17 14:05:48 eggert
42075184b7Schristos * Specify subprocess input via file descriptor, not file name. Remove lint.
43075184b7Schristos *
44075184b7Schristos * Revision 5.16 1993/11/09 17:40:15 eggert
45075184b7Schristos * -V now prints version on stdout and exits. Don't print usage twice.
46075184b7Schristos *
47075184b7Schristos * Revision 5.15 1993/11/03 17:42:27 eggert
48075184b7Schristos * Add -z. Ignore -T. Pass -Vn to `co'. Add Name keyword.
49075184b7Schristos * Put revision numbers in -c output. Improve quality of diagnostics.
50075184b7Schristos *
51075184b7Schristos * Revision 5.14 1992/07/28 16:12:44 eggert
52075184b7Schristos * Add -V. Use co -M for better dates with traditional diff -c.
53075184b7Schristos *
54075184b7Schristos * Revision 5.13 1992/02/17 23:02:23 eggert
55075184b7Schristos * Output more readable context diff headers.
56075184b7Schristos * Suppress needless checkout and comparison of identical revisions.
57075184b7Schristos *
58075184b7Schristos * Revision 5.12 1992/01/24 18:44:19 eggert
59075184b7Schristos * Add GNU diff 1.15.2's new options. lint -> RCS_lint
60075184b7Schristos *
61075184b7Schristos * Revision 5.11 1992/01/06 02:42:34 eggert
62075184b7Schristos * Update usage string.
63075184b7Schristos *
64075184b7Schristos * Revision 5.10 1991/10/07 17:32:46 eggert
65075184b7Schristos * Remove lint.
66075184b7Schristos *
67075184b7Schristos * Revision 5.9 1991/08/19 03:13:55 eggert
68075184b7Schristos * Add RCSINIT, -r$. Tune.
69075184b7Schristos *
70075184b7Schristos * Revision 5.8 1991/04/21 11:58:21 eggert
71075184b7Schristos * Add -x, RCSINIT, MS-DOS support.
72075184b7Schristos *
73075184b7Schristos * Revision 5.7 1990/12/13 06:54:07 eggert
74075184b7Schristos * GNU diff 1.15 has -u.
75075184b7Schristos *
76075184b7Schristos * Revision 5.6 1990/11/01 05:03:39 eggert
77075184b7Schristos * Remove unneeded setid check.
78075184b7Schristos *
79075184b7Schristos * Revision 5.5 1990/10/04 06:30:19 eggert
80075184b7Schristos * Accumulate exit status across files.
81075184b7Schristos *
82075184b7Schristos * Revision 5.4 1990/09/27 01:31:43 eggert
83075184b7Schristos * Yield 1, not EXIT_FAILURE, when diffs are found.
84075184b7Schristos *
85075184b7Schristos * Revision 5.3 1990/09/11 02:41:11 eggert
86075184b7Schristos * Simplify -kkvl test.
87075184b7Schristos *
88075184b7Schristos * Revision 5.2 1990/09/04 17:07:19 eggert
89075184b7Schristos * Diff's argv was too small by 1.
90075184b7Schristos *
91075184b7Schristos * Revision 5.1 1990/08/29 07:13:55 eggert
92075184b7Schristos * Add -kkvl.
93075184b7Schristos *
94075184b7Schristos * Revision 5.0 1990/08/22 08:12:46 eggert
95075184b7Schristos * Add -k, -V. Don't use access(). Add setuid support.
96075184b7Schristos * Remove compile-time limits; use malloc instead.
97075184b7Schristos * Don't pass arguments with leading '+' to diff; GNU DIFF treats them as options.
98075184b7Schristos * Add GNU diff's flags. Make lock and temp files faster and safer.
99075184b7Schristos * Ansify and Posixate.
100075184b7Schristos *
101075184b7Schristos * Revision 4.6 89/05/01 15:12:27 narten
102075184b7Schristos * changed copyright header to reflect current distribution rules
103075184b7Schristos *
104075184b7Schristos * Revision 4.5 88/08/09 19:12:41 eggert
105075184b7Schristos * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
106075184b7Schristos *
107075184b7Schristos * Revision 4.4 87/12/18 11:37:46 narten
108075184b7Schristos * changes Jay Lepreau made in the 4.3 BSD version, to add support for
109075184b7Schristos * "-i", "-w", and "-t" flags and to permit flags to be bundled together,
110075184b7Schristos * merged in.
111075184b7Schristos *
112075184b7Schristos * Revision 4.3 87/10/18 10:31:42 narten
113075184b7Schristos * Updating version numbers. Changes relative to 1.1 actually
114075184b7Schristos * relative to 4.1
115075184b7Schristos *
116075184b7Schristos * Revision 1.3 87/09/24 13:59:21 narten
117075184b7Schristos * Sources now pass through lint (if you ignore printf/sprintf/fprintf
118075184b7Schristos * warnings)
119075184b7Schristos *
120075184b7Schristos * Revision 1.2 87/03/27 14:22:15 jenkins
121075184b7Schristos * Port to suns
122075184b7Schristos *
123075184b7Schristos * Revision 4.1 83/05/03 22:13:19 wft
124075184b7Schristos * Added default branch, option -q, exit status like diff.
125075184b7Schristos * Added fterror() to replace faterror().
126075184b7Schristos *
127075184b7Schristos * Revision 3.6 83/01/15 17:52:40 wft
128075184b7Schristos * Expanded mainprogram to handle multiple RCS files.
129075184b7Schristos *
130075184b7Schristos * Revision 3.5 83/01/06 09:33:45 wft
131075184b7Schristos * Fixed passing of -c (context) option to diff.
132075184b7Schristos *
133075184b7Schristos * Revision 3.4 82/12/24 15:28:38 wft
134075184b7Schristos * Added call to catchsig().
135075184b7Schristos *
136075184b7Schristos * Revision 3.3 82/12/10 16:08:17 wft
137075184b7Schristos * Corrected checking of return code from diff; improved error msgs.
138075184b7Schristos *
139075184b7Schristos * Revision 3.2 82/12/04 13:20:09 wft
140075184b7Schristos * replaced getdelta() with gettree(). Changed diagnostics.
141075184b7Schristos *
142075184b7Schristos * Revision 3.1 82/11/28 19:25:04 wft
143075184b7Schristos * Initial revision.
144075184b7Schristos *
145075184b7Schristos */
146075184b7Schristos #include "rcsbase.h"
147075184b7Schristos
148075184b7Schristos #if DIFF_L
149075184b7Schristos static char const *setup_label P((struct buf*,char const*,char const[datesize]));
150075184b7Schristos #endif
151075184b7Schristos static void cleanup P((void));
152075184b7Schristos
153075184b7Schristos static int exitstatus;
154075184b7Schristos static RILE *workptr;
155075184b7Schristos static struct stat workstat;
156075184b7Schristos
157075184b7Schristos mainProg(rcsdiffId, "rcsdiff", "Id: rcsdiff.c,v 5.19 1995/06/16 06:19:24 eggert Exp ")
158075184b7Schristos {
159075184b7Schristos static char const cmdusage[] =
160075184b7Schristos "\nrcsdiff usage: rcsdiff -ksubst -q -rrev1 [-rrev2] -Vn -xsuff -zzone [diff options] file ...";
161075184b7Schristos
162075184b7Schristos int revnums; /* counter for revision numbers given */
163075184b7Schristos char const *rev1, *rev2; /* revision numbers from command line */
164075184b7Schristos char const *xrev1, *xrev2; /* expanded revision numbers */
165075184b7Schristos char const *expandarg, *lexpandarg, *suffixarg, *versionarg, *zonearg;
166075184b7Schristos #if DIFF_L
167075184b7Schristos static struct buf labelbuf[2];
168075184b7Schristos int file_labels;
169075184b7Schristos char const **diff_label1, **diff_label2;
170075184b7Schristos char date2[datesize];
171075184b7Schristos #endif
172075184b7Schristos char const *cov[10 + !DIFF_L];
173075184b7Schristos char const **diffv, **diffp, **diffpend; /* argv for subsidiary diff */
174075184b7Schristos char const **pp, *p, *diffvstr;
175075184b7Schristos struct buf commarg;
176075184b7Schristos struct buf numericrev; /* expanded revision number */
177075184b7Schristos struct hshentries *gendeltas; /* deltas to be generated */
178075184b7Schristos struct hshentry * target;
179075184b7Schristos char *a, *dcp, **newargv;
180075184b7Schristos int no_diff_means_no_output;
181*0d69c6cfSchristos int c;
182075184b7Schristos
183075184b7Schristos exitstatus = DIFF_SUCCESS;
184075184b7Schristos
185075184b7Schristos bufautobegin(&commarg);
186075184b7Schristos bufautobegin(&numericrev);
187075184b7Schristos revnums = 0;
188075184b7Schristos rev1 = rev2 = xrev2 = 0;
189075184b7Schristos #if DIFF_L
190075184b7Schristos file_labels = 0;
191075184b7Schristos #endif
192075184b7Schristos expandarg = suffixarg = versionarg = zonearg = 0;
193075184b7Schristos no_diff_means_no_output = true;
194075184b7Schristos suffixes = X_DEFAULT;
195075184b7Schristos
196075184b7Schristos /*
197075184b7Schristos * Room for runv extra + args [+ --binary] [+ 2 labels]
198075184b7Schristos * + 1 file + 1 trailing null.
199075184b7Schristos */
200075184b7Schristos diffv = tnalloc(char const*, 1 + argc + !!OPEN_O_BINARY + 2*DIFF_L + 2);
201075184b7Schristos diffp = diffv + 1;
202075184b7Schristos *diffp++ = DIFF;
203075184b7Schristos
204075184b7Schristos argc = getRCSINIT(argc, argv, &newargv);
205075184b7Schristos argv = newargv;
206075184b7Schristos while (a = *++argv, 0<--argc && *a++=='-') {
207075184b7Schristos dcp = a;
208075184b7Schristos while ((c = *a++)) switch (c) {
209075184b7Schristos case 'r':
210075184b7Schristos switch (++revnums) {
211075184b7Schristos case 1: rev1=a; break;
212075184b7Schristos case 2: rev2=a; break;
213075184b7Schristos default: error("too many revision numbers");
214075184b7Schristos }
215075184b7Schristos goto option_handled;
216075184b7Schristos case '-': case 'D':
217075184b7Schristos no_diff_means_no_output = false;
218075184b7Schristos /* fall into */
219*0d69c6cfSchristos case 'C': case 'F': case 'I': case 'L': case 'W': case 'U':
220075184b7Schristos #if DIFF_L
221*0d69c6cfSchristos if (c == 'L' && file_labels++ == 2)
222075184b7Schristos faterror("too many -L options");
223075184b7Schristos #endif
224075184b7Schristos *dcp++ = c;
225075184b7Schristos if (*a)
226075184b7Schristos do *dcp++ = *a++;
227075184b7Schristos while (*a);
228075184b7Schristos else {
229075184b7Schristos if (!--argc)
230075184b7Schristos faterror("-%c needs following argument%s",
231075184b7Schristos c, cmdusage
232075184b7Schristos );
233075184b7Schristos *diffp++ = *argv++;
234075184b7Schristos }
235075184b7Schristos break;
236075184b7Schristos case 'y':
237075184b7Schristos no_diff_means_no_output = false;
238075184b7Schristos /* fall into */
239075184b7Schristos case 'B': case 'H':
240075184b7Schristos case '0': case '1': case '2': case '3': case '4':
241075184b7Schristos case '5': case '6': case '7': case '8': case '9':
242075184b7Schristos case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
243075184b7Schristos case 'h': case 'i': case 'n': case 'p':
244075184b7Schristos case 't': case 'u': case 'w':
245075184b7Schristos *dcp++ = c;
246075184b7Schristos break;
247075184b7Schristos case 'q':
248075184b7Schristos quietflag=true;
249075184b7Schristos break;
250075184b7Schristos case 'x':
251075184b7Schristos suffixarg = *argv;
252075184b7Schristos suffixes = *argv + 2;
253075184b7Schristos goto option_handled;
254075184b7Schristos case 'z':
255075184b7Schristos zonearg = *argv;
256075184b7Schristos zone_set(*argv + 2);
257075184b7Schristos goto option_handled;
258075184b7Schristos case 'T':
259075184b7Schristos /* Ignore -T, so that RCSINIT can contain -T. */
260075184b7Schristos if (*a)
261075184b7Schristos goto unknown;
262075184b7Schristos break;
263075184b7Schristos case 'V':
264075184b7Schristos versionarg = *argv;
265075184b7Schristos setRCSversion(versionarg);
266075184b7Schristos goto option_handled;
267075184b7Schristos case 'k':
268075184b7Schristos expandarg = *argv;
269075184b7Schristos if (0 <= str2expmode(expandarg+2))
270075184b7Schristos goto option_handled;
271075184b7Schristos /* fall into */
272075184b7Schristos default:
273075184b7Schristos unknown:
274075184b7Schristos error("unknown option: %s%s", *argv, cmdusage);
275075184b7Schristos };
276075184b7Schristos option_handled:
277075184b7Schristos if (dcp != *argv+1) {
278075184b7Schristos *dcp = 0;
279075184b7Schristos *diffp++ = *argv;
280075184b7Schristos }
281075184b7Schristos } /* end of option processing */
282075184b7Schristos
283075184b7Schristos for (pp = diffv+2, c = 0; pp<diffp; )
284075184b7Schristos c += strlen(*pp++) + 1;
285075184b7Schristos diffvstr = a = tnalloc(char, c + 1);
286075184b7Schristos for (pp = diffv+2; pp<diffp; ) {
287075184b7Schristos p = *pp++;
288075184b7Schristos *a++ = ' ';
289075184b7Schristos while ((*a = *p++))
290075184b7Schristos a++;
291075184b7Schristos }
292075184b7Schristos *a = 0;
293075184b7Schristos
294075184b7Schristos #if DIFF_L
295075184b7Schristos diff_label1 = diff_label2 = 0;
296075184b7Schristos if (file_labels < 2) {
297075184b7Schristos if (!file_labels)
298075184b7Schristos diff_label1 = diffp++;
299075184b7Schristos diff_label2 = diffp++;
300075184b7Schristos }
301075184b7Schristos #endif
302075184b7Schristos diffpend = diffp;
303075184b7Schristos
304075184b7Schristos cov[1] = CO;
305075184b7Schristos cov[2] = "-q";
306075184b7Schristos # if !DIFF_L
307075184b7Schristos cov[3] = "-M";
308075184b7Schristos # endif
309075184b7Schristos
310075184b7Schristos /* Now handle all pathnames. */
311075184b7Schristos if (nerror)
312075184b7Schristos cleanup();
313075184b7Schristos else if (argc < 1)
314075184b7Schristos faterror("no input file%s", cmdusage);
315075184b7Schristos else
316075184b7Schristos for (; 0 < argc; cleanup(), ++argv, --argc) {
317075184b7Schristos ffree();
318075184b7Schristos
319075184b7Schristos if (pairnames(argc, argv, rcsreadopen, true, false) <= 0)
320075184b7Schristos continue;
321075184b7Schristos diagnose("===================================================================\nRCS file: %s\n",RCSname);
322075184b7Schristos if (!rev2) {
323075184b7Schristos /* Make sure work file is readable, and get its status. */
324075184b7Schristos if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
325075184b7Schristos eerror(workname);
326075184b7Schristos continue;
327075184b7Schristos }
328075184b7Schristos }
329075184b7Schristos
330075184b7Schristos
331075184b7Schristos gettree(); /* reads in the delta tree */
332075184b7Schristos
333075184b7Schristos if (!Head) {
334075184b7Schristos rcserror("no revisions present");
335075184b7Schristos continue;
336075184b7Schristos }
337075184b7Schristos if (revnums==0 || !*rev1)
338075184b7Schristos rev1 = Dbranch ? Dbranch : Head->num;
339075184b7Schristos
340075184b7Schristos if (!fexpandsym(rev1, &numericrev, workptr)) continue;
341075184b7Schristos if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue;
342075184b7Schristos xrev1=target->num;
343075184b7Schristos #if DIFF_L
344075184b7Schristos if (diff_label1)
345075184b7Schristos *diff_label1 = setup_label(&labelbuf[0], target->num, target->date);
346075184b7Schristos #endif
347075184b7Schristos
348075184b7Schristos lexpandarg = expandarg;
349075184b7Schristos if (revnums==2) {
350075184b7Schristos if (!fexpandsym(
351075184b7Schristos *rev2 ? rev2 : Dbranch ? Dbranch : Head->num,
352075184b7Schristos &numericrev,
353075184b7Schristos workptr
354075184b7Schristos ))
355075184b7Schristos continue;
356075184b7Schristos if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue;
357075184b7Schristos xrev2=target->num;
358075184b7Schristos if (no_diff_means_no_output && xrev1 == xrev2)
359075184b7Schristos continue;
360075184b7Schristos } else if (
361075184b7Schristos target->lockedby
362075184b7Schristos && !lexpandarg
363075184b7Schristos && Expand == KEYVAL_EXPAND
364075184b7Schristos && WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
365075184b7Schristos )
366075184b7Schristos lexpandarg = "-kkvl";
367075184b7Schristos Izclose(&workptr);
368075184b7Schristos #if DIFF_L
369*0d69c6cfSchristos if (diff_label2) {
370075184b7Schristos if (revnums == 2)
371075184b7Schristos *diff_label2 = setup_label(&labelbuf[1], target->num, target->date);
372075184b7Schristos else {
373075184b7Schristos time2date(workstat.st_mtime, date2);
374075184b7Schristos *diff_label2 = setup_label(&labelbuf[1], (char*)0, date2);
375075184b7Schristos }
376*0d69c6cfSchristos }
377075184b7Schristos #endif
378075184b7Schristos
379075184b7Schristos diagnose("retrieving revision %s\n", xrev1);
380075184b7Schristos bufscpy(&commarg, "-p");
381075184b7Schristos bufscat(&commarg, rev1); /* not xrev1, for $Name's sake */
382075184b7Schristos
383075184b7Schristos pp = &cov[3 + !DIFF_L];
384075184b7Schristos *pp++ = commarg.string;
385075184b7Schristos if (lexpandarg) *pp++ = lexpandarg;
386075184b7Schristos if (suffixarg) *pp++ = suffixarg;
387075184b7Schristos if (versionarg) *pp++ = versionarg;
388075184b7Schristos if (zonearg) *pp++ = zonearg;
389075184b7Schristos *pp++ = RCSname;
390075184b7Schristos *pp = 0;
391075184b7Schristos
392075184b7Schristos diffp = diffpend;
393075184b7Schristos # if OPEN_O_BINARY
394075184b7Schristos if (Expand == BINARY_EXPAND)
395075184b7Schristos *diffp++ = "--binary";
396075184b7Schristos # endif
397075184b7Schristos diffp[0] = maketemp(0);
398075184b7Schristos if (runv(-1, diffp[0], cov)) {
399075184b7Schristos rcserror("co failed");
400075184b7Schristos continue;
401075184b7Schristos }
402075184b7Schristos if (!rev2) {
403075184b7Schristos diffp[1] = workname;
404075184b7Schristos if (*workname == '-') {
405075184b7Schristos char *dp = ftnalloc(char, strlen(workname)+3);
406075184b7Schristos diffp[1] = dp;
407075184b7Schristos *dp++ = '.';
408075184b7Schristos *dp++ = SLASH;
409075184b7Schristos VOID strcpy(dp, workname);
410075184b7Schristos }
411075184b7Schristos } else {
412075184b7Schristos diagnose("retrieving revision %s\n",xrev2);
413075184b7Schristos bufscpy(&commarg, "-p");
414075184b7Schristos bufscat(&commarg, rev2); /* not xrev2, for $Name's sake */
415075184b7Schristos cov[3 + !DIFF_L] = commarg.string;
416075184b7Schristos diffp[1] = maketemp(1);
417075184b7Schristos if (runv(-1, diffp[1], cov)) {
418075184b7Schristos rcserror("co failed");
419075184b7Schristos continue;
420075184b7Schristos }
421075184b7Schristos }
422075184b7Schristos if (!rev2)
423075184b7Schristos diagnose("diff%s -r%s %s\n", diffvstr, xrev1, workname);
424075184b7Schristos else
425075184b7Schristos diagnose("diff%s -r%s -r%s\n", diffvstr, xrev1, xrev2);
426075184b7Schristos
427075184b7Schristos diffp[2] = 0;
428075184b7Schristos switch (runv(-1, (char*)0, diffv)) {
429075184b7Schristos case DIFF_SUCCESS:
430075184b7Schristos break;
431075184b7Schristos case DIFF_FAILURE:
432075184b7Schristos if (exitstatus == DIFF_SUCCESS)
433075184b7Schristos exitstatus = DIFF_FAILURE;
434075184b7Schristos break;
435075184b7Schristos default:
436075184b7Schristos workerror("diff failed");
437075184b7Schristos }
438075184b7Schristos }
439075184b7Schristos
440075184b7Schristos tempunlink();
441075184b7Schristos exitmain(exitstatus);
442075184b7Schristos }
443075184b7Schristos
444075184b7Schristos static void
cleanup()445075184b7Schristos cleanup()
446075184b7Schristos {
447075184b7Schristos if (nerror) exitstatus = DIFF_TROUBLE;
448075184b7Schristos Izclose(&finptr);
449075184b7Schristos Izclose(&workptr);
450075184b7Schristos }
451075184b7Schristos
452075184b7Schristos #if RCS_lint
453075184b7Schristos # define exiterr rdiffExit
454075184b7Schristos #endif
455075184b7Schristos void
exiterr()456075184b7Schristos exiterr()
457075184b7Schristos {
458075184b7Schristos tempunlink();
459075184b7Schristos _exit(DIFF_TROUBLE);
460075184b7Schristos }
461075184b7Schristos
462075184b7Schristos #if DIFF_L
463075184b7Schristos static char const *
setup_label(b,num,date)464075184b7Schristos setup_label(b, num, date)
465075184b7Schristos struct buf *b;
466075184b7Schristos char const *num;
467075184b7Schristos char const date[datesize];
468075184b7Schristos {
469075184b7Schristos char *p;
470075184b7Schristos char datestr[datesize + zonelenmax];
471075184b7Schristos VOID date2str(date, datestr);
472075184b7Schristos bufalloc(b,
473075184b7Schristos strlen(workname)
474075184b7Schristos + sizeof datestr + 4
475075184b7Schristos + (num ? strlen(num) : 0)
476075184b7Schristos );
477075184b7Schristos p = b->string;
478075184b7Schristos if (num)
479075184b7Schristos VOID sprintf(p, "-L%s\t%s\t%s", workname, datestr, num);
480075184b7Schristos else
481075184b7Schristos VOID sprintf(p, "-L%s\t%s", workname, datestr);
482075184b7Schristos return p;
483075184b7Schristos }
484075184b7Schristos #endif
485