View | Details | Raw Unified | Return to bug 102609
Collapse All | Expand All

(-)src/bin/date/date.c (-15 / +77 lines)
Lines 66-71 Link Here
66
int retval;
66
int retval;
67
67
68
static void setthetime(const char *, const char *, int, int);
68
static void setthetime(const char *, const char *, int, int);
69
static char *strndup(const char *, int);
70
static int  parseformat(const char *, const char **, const char **);
69
static void badformat(void);
71
static void badformat(void);
70
static void usage(void);
72
static void usage(void);
71
73
Lines 76-81 Link Here
76
	int ch, rflag;
78
	int ch, rflag;
77
	int jflag, nflag;
79
	int jflag, nflag;
78
	const char *format;
80
	const char *format;
81
	const char *format2;	/* Format part to right of "%*", if any. */
82
	int filtermode;		/* True if "%*" occured. */
83
	size_t linelen;
84
	char *line;
79
	char buf[1024];
85
	char buf[1024];
80
	char *endptr, *fmt;
86
	char *endptr, *fmt;
81
	char *tmp;
87
	char *tmp;
Lines 144-153 Link Here
144
		err(1, "time");
150
		err(1, "time");
145
151
146
	format = "%+";
152
	format = "%+";
153
	format2 = "";
154
	line = NULL;
155
	filtermode = 0;
147
156
148
	/* allow the operands in any order */
157
	/* allow the operands in any order */
149
	if (*argv && **argv == '+') {
158
	if (*argv && **argv == '+') {
150
		format = *argv + 1;
159
		filtermode = parseformat(*argv + 1, &format, &format2);
151
		++argv;
160
		++argv;
152
	}
161
	}
153
162
Lines 158-179 Link Here
158
		usage();
167
		usage();
159
168
160
	if (*argv && **argv == '+')
169
	if (*argv && **argv == '+')
161
		format = *argv + 1;
170
		filtermode = parseformat(*argv + 1, &format, &format2);
162
171
163
	lt = *localtime(&tval);
172
	do {
164
	badv = vary_apply(v, &lt);
173
		if (filtermode) {
165
	if (badv) {
174
			if ((line = fgetln(stdin, &linelen)) == NULL)
166
		fprintf(stderr, "%s: Cannot apply date adjustment\n",
175
				break;
167
			badv->arg);
176
			if (linelen != 0 && line[linelen - 1] == '\n')
168
		vary_destroy(v);
177
				linelen--;
169
		usage();
178
			if (!rflag)
170
	}
179
				tval = time(NULL);
171
	vary_destroy(v);
180
		}
172
	(void)strftime(buf, sizeof(buf), format, &lt);
181
		lt = *localtime(&tval);
173
	(void)printf("%s\n", buf);
182
		badv = vary_apply(v, &lt);
174
	if (fflush(stdout))
183
		if (badv) {
175
		err(1, "stdout");
184
			fprintf(stderr, "%s: Cannot apply date adjustment\n",
185
				badv->arg);
186
			vary_destroy(v);
187
			usage();
188
		}
189
		if (*format) {
190
			strftime(buf, sizeof(buf), format, &lt);
191
			printf("%s", buf);
192
		}
193
		if (filtermode) {
194
			fwrite(line, linelen, 1, stdout);
195
			if (*format2) {
196
				strftime(buf, sizeof(buf), format2, &lt);
197
				printf("%s", buf);
198
			}
199
		}
200
		printf("\n");
201
		if (fflush(stdout))
202
			err(1, "stdout");
203
	} while (filtermode);
176
	exit(retval);
204
	exit(retval);
205
}
206
207
static char *
208
strndup(const char *src, int num)
209
{
210
	char *dst;
211
212
	if ((dst = malloc(num + 1)) == NULL)
213
		return (NULL);
214
	dst[num] = '\0';
215
	return (strncpy(dst, src, num));
216
}
217
218
static int
219
parseformat(const char *src, const char **prefix, const char **suffix)
220
{
221
	const char *fptr;
222
	int percent;
223
224
	percent = 0;
225
	for (fptr = src; *fptr; fptr++) {	/* Scan string for "%*". */
226
		if (*fptr == '%')
227
			percent = !percent;
228
		else if (*fptr == '*' && percent) {
229
			if ((*prefix = strndup(src, fptr - src - 1)) == NULL
230
			    || (*suffix = strdup(fptr + 1)) == NULL)
231
				err(1, "malloc");
232
			return (1);	/* filtermode on */
233
		}
234
		else
235
			percent = 0;
236
	}
237
	*prefix = src;
238
	return (0);	/* filtermode off */
177
}
239
}
178
240
179
#define	ATOI2(s)	((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
241
#define	ATOI2(s)	((s) += 2, ((s)[-2] - '0') * 10 + ((s)[-1] - '0'))
(-)src/bin/date/date.1 (+11 lines)
Lines 253-258 Link Here
253
The format string for the default display is
253
The format string for the default display is
254
.Dq +%+ .
254
.Dq +%+ .
255
.Pp
255
.Pp
256
As a special extension, if the format string contains the specification
257
.Dq %* ,
258
.Nm
259
enters filter mode.
260
In that mode, lines are read from stdin.  For each line,
261
a current time stamp is created according to the format string,
262
the line read from stdin is inserted in place of the specification
263
.Dq %* ,
264
and the result is written to stdout.
265
This feature can be used to add time stamps to log files on the fly.
266
.Pp
256
If an operand does not have a leading plus sign, it is interpreted as
267
If an operand does not have a leading plus sign, it is interpreted as
257
a value for setting the system's notion of the current date and time.
268
a value for setting the system's notion of the current date and time.
258
The canonical representation for setting the date and time is:
269
The canonical representation for setting the date and time is:

Return to bug 102609