1 /* $OpenBSD: ident.c,v 1.32 2016/08/26 09:02:54 guenther Exp $ */
2 /*
3 * Copyright (c) 2005 Xavier Santolaria <xsa@openbsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <ctype.h>
28 #include <err.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include <unistd.h>
33
34 #include "rcsprog.h"
35
36 #define KEYDELIM '$' /* keywords delimiter */
37 #define VALDELIM ':' /* values delimiter */
38
39 static int found = 0;
40 static int flags = 0;
41
42 static void ident_file(const char *, FILE *);
43 static void ident_line(FILE *);
44
45 int
ident_main(int argc,char ** argv)46 ident_main(int argc, char **argv)
47 {
48 int i, ch, status;
49 FILE *fp;
50
51 status = 0;
52
53 while ((ch = rcs_getopt(argc, argv, "qV")) != -1) {
54 switch(ch) {
55 case 'q':
56 flags |= QUIET;
57 break;
58 case 'V':
59 printf("%s\n", rcs_version);
60 exit(0);
61 default:
62 (usage)();
63 }
64 }
65
66 argc -= rcs_optind;
67 argv += rcs_optind;
68
69 if (argc == 0)
70 ident_file(NULL, stdin);
71 else {
72 for (i = 0; i < argc; i++) {
73 if ((fp = fopen(argv[i], "r")) == NULL) {
74 warn("%s", argv[i]);
75 status = 1;
76 continue;
77 }
78
79 ident_file(argv[i], fp);
80 (void)fclose(fp);
81 if (i != argc - 1)
82 printf("\n");
83 }
84 }
85
86 return (status);
87 }
88
89
90 static void
ident_file(const char * filename,FILE * fp)91 ident_file(const char *filename, FILE *fp)
92 {
93 int c;
94
95 if (filename != NULL)
96 printf("%s:\n", filename);
97 else
98 filename = "standard input";
99
100 for (c = 0; c != EOF; c = getc(fp)) {
101 if (feof(fp) || ferror(fp))
102 break;
103 if (c == KEYDELIM)
104 ident_line(fp);
105 }
106
107 if (found == 0 && !(flags & QUIET))
108 fprintf(stderr, "ident warning: no id keywords in %s\n",
109 filename);
110
111 found = 0;
112 }
113
114 static void
ident_line(FILE * fp)115 ident_line(FILE *fp)
116 {
117 int c;
118 BUF *bp;
119 size_t len;
120
121 bp = buf_alloc(512);
122
123 while ((c = getc(fp)) != VALDELIM) {
124 if (c == EOF)
125 goto out;
126
127 if (isalpha(c))
128 buf_putc(bp, c);
129 else
130 goto out;
131 }
132
133 buf_putc(bp, VALDELIM);
134
135 while ((c = getc(fp)) != KEYDELIM) {
136 if (c == EOF)
137 goto out;
138
139 if (c == '\n')
140 goto out;
141
142 buf_putc(bp, c);
143 }
144
145 len = buf_len(bp);
146 if (buf_getc(bp, len - 1) != ' ')
147 goto out;
148
149 /* append trailing KEYDELIM */
150 buf_putc(bp, c);
151
152 /* Append newline for printing. */
153 buf_putc(bp, '\n');
154 printf(" %c", KEYDELIM);
155 fflush(stdout);
156 buf_write_fd(bp, STDOUT_FILENO);
157
158 found++;
159 out:
160 buf_free(bp);
161 }
162
163 __dead void
ident_usage(void)164 ident_usage(void)
165 {
166 fprintf(stderr, "usage: ident [-qV] [file ...]\n");
167
168 exit(1);
169 }
170