]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blob - db/input.c
Update copyright dates
[thirdparty/xfsprogs-dev.git] / db / input.c
1 /*
2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33 #include <libxfs.h>
34 #include <signal.h>
35 #include "command.h"
36 #include "data.h"
37 #include "input.h"
38 #include "output.h"
39 #include "sig.h"
40 #include "malloc.h"
41 #include "init.h"
42
43 int inputstacksize;
44 FILE **inputstack;
45 FILE *curinput;
46
47 static void popfile(void);
48 static int source_f(int argc, char **argv);
49
50 static const cmdinfo_t source_cmd =
51 { "source", NULL, source_f, 1, 1, 0, "source-file",
52 "get commands from source-file", NULL };
53
54 /* our homegrown strtok that understands strings */
55
56 static char *
57 tokenize(
58 char *inp)
59 {
60 static char *last_place = NULL;
61 char *start;
62 char *walk;
63 int in_string = 0;
64 int in_escape = 0;
65
66 if (inp) {
67 start = inp;
68 } else {
69 if (last_place == NULL)
70 return NULL;
71
72 /* we're done */
73 if (*last_place != '\0')
74 return NULL;
75
76 start = last_place + 1;
77 }
78 last_place = NULL;
79
80 /* eat whitespace */
81 while (*start == ' ' || *start == '\t')
82 start++;
83
84 walk = start;
85 for (;*walk != '\0'; walk++) {
86 if (in_escape) {
87 in_escape = 0;
88 continue;
89 }
90 if (*walk == '\\')
91 in_escape = 1;
92 else if (*walk == '\"')
93 in_string ^= 1;
94
95 if (!in_string && !in_escape &&
96 (*walk == ' ' || *walk == '\t')) {
97 last_place = walk;
98 *last_place = '\0';
99 break;
100 }
101 }
102 if (walk == start)
103 return NULL;
104
105 return start;
106 }
107
108 char **
109 breakline(
110 char *input,
111 int *count)
112 {
113 int c;
114 char *inp;
115 char *p;
116 char **rval;
117
118 c = 0;
119 inp = input;
120 rval = xcalloc(sizeof(char *), 1);
121 for (;;) {
122
123 p = tokenize(inp);
124
125 if (p == NULL)
126 break;
127 inp = NULL;
128 c++;
129 rval = xrealloc(rval, sizeof(*rval) * (c + 1));
130 rval[c - 1] = p;
131 rval[c] = NULL;
132 }
133 *count = c;
134 return rval;
135 }
136
137 void
138 doneline(
139 char *input,
140 char **vec)
141 {
142 xfree(input);
143 xfree(vec);
144 }
145
146 char *
147 fetchline(void)
148 {
149 char buf[1024];
150 int iscont;
151 size_t len;
152 size_t rlen;
153 char *rval;
154
155 rval = NULL;
156 for (rlen = iscont = 0; ; ) {
157 if (inputstacksize == 1) {
158 if (iscont)
159 dbprintf("... ");
160 else
161 dbprintf("%s: ", progname);
162 fflush(stdin);
163 }
164 if (seenint() ||
165 (!fgets(buf, sizeof(buf), curinput) &&
166 ferror(curinput) && seenint())) {
167 clearint();
168 dbprintf("^C\n");
169 clearerr(curinput);
170 if (iscont) {
171 iscont = 0;
172 rlen = 0;
173 if (rval) {
174 xfree(rval);
175 rval = NULL;
176 }
177 }
178 continue;
179 }
180 if (ferror(curinput) || feof(curinput) ||
181 (len = strlen(buf)) == 0) {
182 popfile();
183 if (curinput == NULL) {
184 dbprintf("\n");
185 return NULL;
186 }
187 iscont = 0;
188 rlen = 0;
189 if (rval) {
190 xfree(rval);
191 rval = NULL;
192 }
193 continue;
194 }
195 if (inputstacksize == 1)
196 logprintf("%s", buf);
197 rval = xrealloc(rval, rlen + len + 1);
198 if (rlen == 0)
199 rval[0] = '\0';
200 rlen += len;
201 strcat(rval, buf);
202 if (buf[len - 1] == '\n') {
203 if (len > 1 && buf[len - 2] == '\\') {
204 rval[rlen - 2] = ' ';
205 rval[rlen - 1] = '\0';
206 rlen--;
207 iscont = 1;
208 } else {
209 rval[rlen - 1] = '\0';
210 rlen--;
211 break;
212 }
213 }
214 }
215 return rval;
216 }
217
218 void
219 input_init(void)
220 {
221 add_command(&source_cmd);
222 }
223
224 static void
225 popfile(void)
226 {
227 if (inputstacksize == 0) {
228 curinput = NULL;
229 return;
230 }
231 if (curinput != stdin)
232 fclose(curinput);
233
234 inputstacksize--;
235 if (inputstacksize) {
236 inputstack =
237 xrealloc(inputstack, inputstacksize * sizeof(*inputstack));
238 curinput = inputstack[inputstacksize - 1];
239 } else {
240 free(inputstack);
241 curinput = NULL;
242 inputstack = NULL;
243 }
244 }
245
246 void
247 pushfile(
248 FILE *file)
249 {
250 inputstack =
251 xrealloc(inputstack,
252 (inputstacksize + 1) * sizeof(*inputstack));
253 inputstacksize++;
254 curinput = inputstack[inputstacksize - 1] = file;
255 }
256
257 /* ARGSUSED */
258 static int
259 source_f(
260 int argc,
261 char **argv)
262 {
263 FILE *f;
264
265 f = fopen(argv[1], "r");
266 if (f == NULL)
267 dbprintf("can't open %s\n", argv[0]);
268 else
269 pushfile(f);
270 return 0;
271 }