1*099bc362Sguenther /* $OpenBSD: ident.c,v 1.32 2016/08/26 09:02:54 guenther Exp $ */
2c6e1ac21Sjoris /*
3c6e1ac21Sjoris * Copyright (c) 2005 Xavier Santolaria <xsa@openbsd.org>
4c6e1ac21Sjoris * All rights reserved.
5c6e1ac21Sjoris *
6c6e1ac21Sjoris * Redistribution and use in source and binary forms, with or without
7c6e1ac21Sjoris * modification, are permitted provided that the following conditions
8c6e1ac21Sjoris * are met:
9c6e1ac21Sjoris *
10c6e1ac21Sjoris * 1. Redistributions of source code must retain the above copyright
11c6e1ac21Sjoris * notice, this list of conditions and the following disclaimer.
12c6e1ac21Sjoris * 2. The name of the author may not be used to endorse or promote products
13c6e1ac21Sjoris * derived from this software without specific prior written permission.
14c6e1ac21Sjoris *
15c6e1ac21Sjoris * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16c6e1ac21Sjoris * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17c6e1ac21Sjoris * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18c6e1ac21Sjoris * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19c6e1ac21Sjoris * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20c6e1ac21Sjoris * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21c6e1ac21Sjoris * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22c6e1ac21Sjoris * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23c6e1ac21Sjoris * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24c6e1ac21Sjoris * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25c6e1ac21Sjoris */
26c6e1ac21Sjoris
274781e2faSxsa #include <ctype.h>
284781e2faSxsa #include <err.h>
294781e2faSxsa #include <stdio.h>
304781e2faSxsa #include <stdlib.h>
31*099bc362Sguenther #include <time.h>
324781e2faSxsa #include <unistd.h>
33c6e1ac21Sjoris
34c6e1ac21Sjoris #include "rcsprog.h"
35c6e1ac21Sjoris
36c15aa039Sxsa #define KEYDELIM '$' /* keywords delimiter */
37c15aa039Sxsa #define VALDELIM ':' /* values delimiter */
38c6e1ac21Sjoris
39cf1aeb06Sjoris static int found = 0;
40913586deSxsa static int flags = 0;
41c6e1ac21Sjoris
4230bf5e11Sxsa static void ident_file(const char *, FILE *);
4330bf5e11Sxsa static void ident_line(FILE *);
44c6e1ac21Sjoris
45c6e1ac21Sjoris int
ident_main(int argc,char ** argv)46c6e1ac21Sjoris ident_main(int argc, char **argv)
47c6e1ac21Sjoris {
4874fdd43aSray int i, ch, status;
49c6e1ac21Sjoris FILE *fp;
50c6e1ac21Sjoris
5174fdd43aSray status = 0;
5274fdd43aSray
53a2b34663Sjoris while ((ch = rcs_getopt(argc, argv, "qV")) != -1) {
54c6e1ac21Sjoris switch(ch) {
55c6e1ac21Sjoris case 'q':
56913586deSxsa flags |= QUIET;
57c6e1ac21Sjoris break;
58c6e1ac21Sjoris case 'V':
59c6e1ac21Sjoris printf("%s\n", rcs_version);
60c6e1ac21Sjoris exit(0);
61c6e1ac21Sjoris default:
62c6e1ac21Sjoris (usage)();
63c6e1ac21Sjoris }
64c6e1ac21Sjoris }
65c6e1ac21Sjoris
66a2b34663Sjoris argc -= rcs_optind;
67a2b34663Sjoris argv += rcs_optind;
68c6e1ac21Sjoris
6996b8bf5aSxsa if (argc == 0)
70c6e1ac21Sjoris ident_file(NULL, stdin);
7196b8bf5aSxsa else {
72c6e1ac21Sjoris for (i = 0; i < argc; i++) {
73c6e1ac21Sjoris if ((fp = fopen(argv[i], "r")) == NULL) {
7482ca7eaaSxsa warn("%s", argv[i]);
7574fdd43aSray status = 1;
76c6e1ac21Sjoris continue;
77c6e1ac21Sjoris }
78c6e1ac21Sjoris
79c6e1ac21Sjoris ident_file(argv[i], fp);
8082ca7eaaSxsa (void)fclose(fp);
8174fdd43aSray if (i != argc - 1)
8274fdd43aSray printf("\n");
83c6e1ac21Sjoris }
84c6e1ac21Sjoris }
85c6e1ac21Sjoris
8674fdd43aSray return (status);
87c6e1ac21Sjoris }
88c6e1ac21Sjoris
89c6e1ac21Sjoris
9030bf5e11Sxsa static void
ident_file(const char * filename,FILE * fp)91c6e1ac21Sjoris ident_file(const char *filename, FILE *fp)
92c6e1ac21Sjoris {
93c6e1ac21Sjoris int c;
94c6e1ac21Sjoris
95c344b8d6Sxsa if (filename != NULL)
96c6e1ac21Sjoris printf("%s:\n", filename);
97c344b8d6Sxsa else
9884eee8cfSsobrado filename = "standard input";
99c6e1ac21Sjoris
1007249ec9bSderaadt for (c = 0; c != EOF; c = getc(fp)) {
1017249ec9bSderaadt if (feof(fp) || ferror(fp))
102c6e1ac21Sjoris break;
103c6e1ac21Sjoris if (c == KEYDELIM)
104c6e1ac21Sjoris ident_line(fp);
105c6e1ac21Sjoris }
106c6e1ac21Sjoris
107913586deSxsa if (found == 0 && !(flags & QUIET))
108c344b8d6Sxsa fprintf(stderr, "ident warning: no id keywords in %s\n",
109c344b8d6Sxsa filename);
110c344b8d6Sxsa
111c344b8d6Sxsa found = 0;
112c6e1ac21Sjoris }
113c6e1ac21Sjoris
11430bf5e11Sxsa static void
ident_line(FILE * fp)115c6e1ac21Sjoris ident_line(FILE *fp)
116c6e1ac21Sjoris {
117c6e1ac21Sjoris int c;
1188958bb4aSjoris BUF *bp;
1198958bb4aSjoris size_t len;
120c6e1ac21Sjoris
1210ee14128Sray bp = buf_alloc(512);
122c6e1ac21Sjoris
123c6e1ac21Sjoris while ((c = getc(fp)) != VALDELIM) {
1249d739794Sray if (c == EOF)
1258958bb4aSjoris goto out;
126c6e1ac21Sjoris
127c6e1ac21Sjoris if (isalpha(c))
1287bb3ddb0Sray buf_putc(bp, c);
129c6e1ac21Sjoris else
1308958bb4aSjoris goto out;
131c6e1ac21Sjoris }
132c6e1ac21Sjoris
1337bb3ddb0Sray buf_putc(bp, VALDELIM);
134c6e1ac21Sjoris
135c6e1ac21Sjoris while ((c = getc(fp)) != KEYDELIM) {
1369d739794Sray if (c == EOF)
1378958bb4aSjoris goto out;
138c6e1ac21Sjoris
139c6e1ac21Sjoris if (c == '\n')
1408958bb4aSjoris goto out;
141c6e1ac21Sjoris
1427bb3ddb0Sray buf_putc(bp, c);
143c6e1ac21Sjoris }
144c6e1ac21Sjoris
1457bb3ddb0Sray len = buf_len(bp);
1467bb3ddb0Sray if (buf_getc(bp, len - 1) != ' ')
1478958bb4aSjoris goto out;
148c6e1ac21Sjoris
149c6e1ac21Sjoris /* append trailing KEYDELIM */
1507bb3ddb0Sray buf_putc(bp, c);
15151c4a85dSray
15251c4a85dSray /* Append newline for printing. */
1537bb3ddb0Sray buf_putc(bp, '\n');
15451c4a85dSray printf(" %c", KEYDELIM);
155fc4cb550Sray fflush(stdout);
1567bb3ddb0Sray buf_write_fd(bp, STDOUT_FILENO);
157c6e1ac21Sjoris
158cf1aeb06Sjoris found++;
1598958bb4aSjoris out:
1607bb3ddb0Sray buf_free(bp);
161c6e1ac21Sjoris }
162c6e1ac21Sjoris
163960e00beSotto __dead void
ident_usage(void)164c6e1ac21Sjoris ident_usage(void)
165c6e1ac21Sjoris {
16684eee8cfSsobrado fprintf(stderr, "usage: ident [-qV] [file ...]\n");
167960e00beSotto
168960e00beSotto exit(1);
169c6e1ac21Sjoris }
170