1 /* mp3asm: an mp3 frameeditor.
2 *
3 * parse.c : parses the command line input.
4 *
5 * Copyright (C) 2001 Luc Verhaegen (_Death_@Undernet(IRC))
6 * <dw_death_@hotmail.com>
7 * Copyright (C) 1996-1997 Olli Fromme <olli@fromme.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24 #include <unistd.h>
25 #include "mp3asm.h"
26 #include "parse.h"
27 #include "utils.h"
28
29 /* mp3asm.c */
30 extern void new_input (void);
31
32 /* utils.c */
33 extern void *tmalloc (size_t size);
34 extern void print_std (int verb);
35
36 /*
37 * implementing callbacks!
38 *
39 */
40 static void usage (void);
41
42 static void
bad_flag(char * string,int i)43 bad_flag (char *string, int i)
44 {
45 if (!i)
46 sprintf (mp3asm_log.buf, "%s: Bad flag specified: \"%s\"\n", me, string);
47 else
48 sprintf (mp3asm_log.buf, "%s: Bad flag specified: \"%s\" from \"%s\"\n", me, string+i, string);
49 print_std (-1);
50 exit (EX_USAGE);
51 }
52
53 static void
arg_needed(char flag)54 arg_needed (char flag)
55 {
56 sprintf (mp3asm_log.buf, "%s: No argument specified for flag %c\n", me, flag);
57 print_std (-1);
58 exit (EX_USAGE);
59 }
60
61 static void
double_flag(char flag)62 double_flag (char flag)
63 {
64 sprintf (mp3asm_log.buf, "%s: Flag specified twice: \"%c\"\n", me, flag);
65 print_std (-1);
66 exit (EX_USAGE);
67 }
68
69 static void
bad_arg(char * string)70 bad_arg (char *string)
71 {
72 sprintf (mp3asm_log.buf, "%s: Bad argument given: \"%s\"\n", me, string);
73 print_std (-1);
74 exit (EX_USAGE);
75 }
76
77 static int
incr_verbosity(char * arg)78 incr_verbosity (char *arg)
79 {
80 verbosity++;
81 return (0);
82 }
83
84 static int
start_frame(char * arg)85 start_frame (char *arg)
86 {
87 if (input[inputs - 1]->startframe)
88 return (1);
89 if ((input[inputs - 1]->startframe = atol (arg)))
90 return (0);
91 return (2);
92 }
93
94 static int
end_frame(char * arg)95 end_frame (char *arg)
96 {
97 if (input[inputs - 1]->endframe || input[inputs - 1]->readframes)
98 return (1);
99 if ((input[inputs - 1]->endframe = atol (arg)))
100 return (0);
101 return (2);
102 }
103
104 static int
read_frames(char * arg)105 read_frames (char *arg)
106 {
107 if (input[inputs - 1]->readframes || input[inputs - 1]->endframe)
108 return (1);
109 if ((input[inputs - 1]->readframes = atol (arg)))
110 return (0);
111 return (2);
112 }
113
114 static int
use_tag(char * arg)115 use_tag (char *arg)
116 {
117 int i = inputs;
118 while (i)
119 {
120 i--;
121 if (input[inputs - 1]->use_id3)
122 return (1);
123 }
124 input[inputs - 1]->use_id3++;
125 return (0);
126 }
127
128 static int
set_output(char * arg)129 set_output (char *arg)
130 {
131 if (output->name)
132 return (1);
133 output->name = strcpy (tmalloc (strlen (arg) + 1), arg);
134 return (0);
135 }
136
137 static int
report(char * arg)138 report (char *arg)
139 {
140 char *name = tmalloc (1024 * sizeof (char));
141 if (!gethostname (name, 1024))
142 sprintf (mp3asm_log.buf, "Sending notification to the authorities; Illegal use of copyrighted material on %s\n", name);
143 free (name);
144 return (0);
145 }
146
147 static int
use_log(char * arg)148 use_log (char *arg)
149 {
150 if (mp3asm_log.name)
151 return (1);
152 mp3asm_log.name = strcpy (tmalloc (strlen (arg) + 1), arg);
153 return (0);
154 }
155
156 static int
print_help(char * arg)157 print_help (char *arg)
158 {
159 usage ();
160 return (0);
161 }
162
163 #define NO_ARG 0
164 #define NEEDS_ARG 1
165
166 struct parse_flags
167 {
168 char flag;
169 char *help;
170 int (*handler) (char *arg);
171 int args;
172 };
173
174 struct parse_flags parse[] =
175 {
176 {'v', "Increase verbosity.", incr_verbosity, NO_ARG},
177 {'s', "Set the starting frame.", start_frame, NEEDS_ARG},
178 {'e', "Set the ending frame.", end_frame, NEEDS_ARG},
179 {'r', "Set the number of frames to read (conflicts with 'e')", read_frames, NEEDS_ARG},
180 {'t', "Use id3-tag of the file. (should be used only once!)", use_tag, NO_ARG},
181 {'o', "Name of the file to output to. (default = changed input filename)", set_output, NEEDS_ARG},
182 {'N', "Not reporting illegal copyrighte material to the authorities.", report, NO_ARG},
183 {'l', "Log to file.", use_log, NEEDS_ARG},
184 {'h', "Print this help.", print_help, NO_ARG},
185 { 0, NULL, NULL, NO_ARG}
186 };
187
188 static void
usage(void)189 usage (void)
190 {
191 int k = 0;
192
193 sprintf (mp3asm_log.buf, "Usage: %s [options] inputfile.mp3 [...]\n", me);
194 print_std (0);
195 while (parse[k].flag)
196 {
197 sprintf (mp3asm_log.buf, " -%c %s\n", parse[k].flag, parse[k].help);
198 print_std (0);
199 k++;
200 }
201
202 exit (EX_USAGE);
203 }
204
205 /*
206 * Parses an individual argument.
207 *
208 */
209
210 void
parse_argument(int argc,char * argv[])211 parse_argument (int argc, char *argv[])
212 {
213 int strlength, i, j, k, temp;
214
215 for (i = 1; i < argc; ++i)
216 {
217 if (argv[i][0] == '-') /* flag */
218 {
219 strlength = strlen ((char *)argv[i]);
220 for (j = 1 ; j < strlength; ++j)
221 {
222 k = 0;
223 while (parse[k].flag != argv[i][j])
224 {
225 if (parse[k].flag == 0)
226 bad_flag (argv[i], j);
227 k++;
228 }
229 if (parse[k].args == NEEDS_ARG)
230 {
231 if (++j < strlength) /* this is not the last char */
232 {
233 if ((temp = parse[k].handler (argv[i] + j)) == 1)
234 double_flag (argv[i][j - 1]);
235 else if (temp == 2)
236 bad_arg (argv[i] + j);
237 }
238 else if (argv[++i][0] != '-')
239 {
240 if ((temp = parse[k].handler (argv[i])) == 1)
241 double_flag (argv[i - 1][j - 1]);
242 else if (temp == 2)
243 bad_arg (argv[i]);
244
245 }
246 else
247 arg_needed (parse[k].flag);
248 j = strlength;
249 }
250 else
251 {
252 if (parse[k].handler (NULL) == 1)
253 double_flag (argv[i][j] );
254 }
255 }
256 }
257 else /* input file */
258 {
259
260 input[inputs - 1]->name = tmalloc (strlen (argv[i]) + 1);
261 strcpy (input[inputs - 1]->name, argv[i]);
262 /*sprintf (mp3asm_log.buf, "%d input: %s\n", inputs - 1, input[inputs - 1]->name);
263 print_std (5);*/
264 new_input ();
265 }
266 }
267 }
268
269 /*
270 * Check if the options r useable.
271 *
272 */
273
274 static void
check_options()275 check_options ()
276 {
277 int id3=0, i;
278
279 for (i = 0; i < inputs; ++i)
280 {
281 if (input[i]->readframes)
282 input[i]->endframe = input[i]->startframe + input[i]->readframes;
283 else if (input[i]->endframe)
284 input[i]->readframes = input[i]->endframe - input[i]->startframe;
285
286 if ((input[i]->endframe && (input[i]->startframe > input[i]->endframe)) || (input[i]->startframe && (input[i]->startframe == input[i]->endframe)))
287 {
288 sprintf (mp3asm_log.buf, "%s: Invalid options given. The number of frames to skip should be smaller than the number of the last frame to read for \"%s\".\n", me, input[i]->name);
289 print_std (-1);
290 exit (EX_USAGE);
291 }
292
293 if (input[i]->use_id3) {
294 if (id3)
295 {
296 sprintf (mp3asm_log.buf, "%s: Invalid options given. More than one id3 tag specified for use.\n", me);
297 print_std (-1);
298 exit (EX_USAGE);
299 }
300 else
301 ++id3;
302 }
303 }
304 if (input[inputs - 1]->name == NULL)
305 {
306 if (input[inputs -1]->startframe ||input[inputs -1]->endframe || input[inputs -1]->readframes || input[inputs -1]->use_id3)
307 {
308 sprintf (mp3asm_log.buf, "%s: Flags specified for input file, but no input file has been given.\n", me);
309 print_std (-1);
310 exit(EX_USAGE);
311 }
312 free (input[inputs - 1]);
313 inputs--;
314 }
315 if (!inputs)
316 {
317 sprintf (mp3asm_log.buf, "%s: No input files specified.\n", me);
318 print_std (-1);
319 exit (EX_USAGE);
320 }
321 /* else
322 {
323 sprintf (mp3asm_log.buf, "inputs: %d\n", inputs);
324 print_std (5);
325 }*/
326
327 if (!info)
328 {
329 sprintf (mp3asm_log.buf, "%s: Program from Olli Fromme & _Death_.\n", me);
330 print_std (-1);
331
332 if (!output->name)
333 sprintf (mp3asm_log.buf, "%s: Checking the following mp3 files for header errors:\n", me);
334 else
335 sprintf(mp3asm_log.buf, "%s: Taking input from:\n", me);
336 print_std (1);
337
338 for (i = 0; i < inputs; ++i)
339 {
340 sprintf (mp3asm_log.buf, "%s: input %d: %s from frame %ld to %ld [%ld].\n", me, i, input[i]->name, input[i]->startframe, input[i]->endframe, input[i]->readframes);
341 print_std (2);
342 }
343
344 if (!output->name)
345 sprintf (mp3asm_log.buf, "%s: No output file specified.\n", me);
346 else
347 sprintf (mp3asm_log.buf, "%s: Outputting to %s.\n", me, output->name);
348 print_std (1);
349 }
350 }
351
352 /*
353 * Parses the arguments.
354 *
355 */
356
357 void
parse_args(int argc,char * argv[])358 parse_args (int argc, char *argv[])
359 {
360 if (argc < 2)
361 usage();
362
363 parse_argument(argc, argv) ;
364 check_options();
365 }
366
367 /* EOF */
368