source: vendor/emx/current/src/emxomf/emxomfar.c

Last change on this file was 18, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 10.2 KB
Line 
1/* emxomfar.c -- Manage OMF libraries (.LIB files)
2 Copyright (c) 1992-1998 Eberhard Mattes
3
4This file is part of emxomfar.
5
6emxomfar is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11emxomfar is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with emxomfar; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <io.h>
26
27#define VERSION "0.9d"
28
29typedef unsigned char byte;
30typedef unsigned short word;
31
32#include <sys/omflib.h>
33
34#define FALSE 0
35#define TRUE 1
36
37/* The name of the original library file. */
38static char *lib_fname;
39
40/* The name of the new library file. */
41static char *new_fname;
42
43/* This is the command character. */
44static char cmd;
45
46/* This flag is non-zero if the v option is given. */
47static char verbose;
48
49/* This flag is non-zero if the c option is given. */
50static char silent;
51
52/* OMFLIB descriptor of the original library. */
53static struct omflib *lib;
54
55/* OMFLIB descriptor of the new library. */
56static struct omflib *new_lib;
57
58
59/* Tell the user how to run this program. */
60
61static void usage (void)
62{
63 fprintf (stderr, "emxomfar " VERSION " -- "
64 "Copyright (c) 1992-1996 by Eberhard Mattes\n\n");
65 fprintf (stderr, "Usage: emxomfar [-p#] <command> <library_file> [<module>]...\n");
66 fprintf (stderr, "\nCommands:\n");
67 fprintf (stderr, " d delete module from library\n");
68 fprintf (stderr, " r replace modules in library\n");
69 fprintf (stderr, " t list table of contents\n");
70 fprintf (stderr, " x extract modules from library\n");
71 fprintf (stderr, "\nOptions (append to command):\n");
72 fprintf (stderr, " c no warning when creating new library\n");
73 fprintf (stderr, " v verbose output\n");
74 fprintf (stderr, "\nOptions (prededing command):\n");
75 fprintf (stderr, " -p# set page size\n");
76 exit (1);
77}
78
79
80/* This function is passed to omflib_pubdef_walk to list the public
81 symbols. */
82
83static int list_pubdef (const char *name, char *error)
84{
85 printf (" %s\n", name);
86 return 0;
87}
88
89
90/* Perform the requested action for the module NAME. */
91
92static void do_mod (const char *name)
93{
94 char error[512], c;
95 char mod_name[256];
96 int page;
97
98 c = 'a'; page = 0;
99 omflib_module_name (mod_name, name);
100 if (lib != NULL)
101 {
102 page = omflib_find_module (lib, name, error);
103 if (cmd == 'r')
104 {
105 if (page != 0)
106 {
107 c = 'r';
108 if (omflib_mark_deleted (lib, name, error) != 0)
109 {
110 fprintf (stderr, "emxomfar: %s\n", error);
111 exit (2);
112 }
113 }
114 }
115 else if (page == 0)
116 {
117 fprintf (stderr, "emxomfar: Module not found: %s\n", name);
118 return;
119 }
120 }
121 switch (cmd)
122 {
123 case 't':
124 if (verbose)
125 {
126 printf("%s (page %d):\n", mod_name, page);
127 if (omflib_pubdef_walk (lib, page, list_pubdef, error) != 0)
128 fprintf (stderr, "emxomfar: %s\n", error);
129 fputchar ('\n');
130 }
131 else
132 printf ("%s\n", mod_name);
133 break;
134 case 'x':
135 if (verbose)
136 printf ("x - %s\n", name);
137 if (omflib_extract (lib, name, error) != 0)
138 {
139 fprintf (stderr, "emxomfar: %s\n", error);
140 exit (2);
141 }
142 break;
143 case 'r':
144 if (verbose)
145 printf ("%c - %s\n", c, name);
146 if (omflib_add_module (new_lib, name, error) != 0)
147 {
148 fprintf (stderr, "emxomfar: %s(%s): %s\n", new_fname, name, error);
149 exit (2);
150 }
151 break;
152 case 'd':
153 if (verbose)
154 printf ("d - %s\n", mod_name);
155 if (omflib_mark_deleted (lib, name, error) != 0)
156 fprintf (stderr, "emxomfar: %s\n", error);
157 break;
158 }
159}
160
161
162/* Cleanup, for atexit. */
163
164static void cleanup (void)
165{
166 char error[512];
167
168 if (new_fname != NULL)
169 {
170 if (new_lib != NULL)
171 {
172 omflib_close (new_lib, error);
173 new_lib = NULL;
174 }
175 if (lib != NULL)
176 {
177 omflib_close (lib, error);
178 lib = NULL;
179 }
180 remove (new_fname);
181 if (lib_fname != NULL)
182 rename (lib_fname, new_fname);
183 new_fname = NULL;
184 }
185}
186
187
188/* Entrypoint. Parse the command line, open files and perform the
189 requested action. */
190
191int main (int argc, char *argv[])
192{
193 char error[512], name[257], *s, new_cmd;
194 int page;
195 int i, n, create, page_size;
196 char ext_fname[512];
197 char bak_fname[512];
198
199 /* Expand response files and wildcards on th command line. */
200
201 _response (&argc, &argv);
202 _wildcard (&argc, &argv);
203
204 /* The default page size is 16. */
205
206 page_size = 16;
207
208 /* Parse the command line. First, check for an -p# option. */
209
210 i = 1;
211 if (i < argc && argv[i][0] == '-')
212 {
213 s = argv[i]+1;
214 switch (*s)
215 {
216 case 'p':
217 ++s;
218 page_size = strtol (s, &s, 10);
219 if (page_size < 1 || *s != 0)
220 usage ();
221 ++i;
222 break;
223 default:
224 usage ();
225 }
226 }
227
228 /* At least 2 arguments must be given: the command and the library
229 name. */
230
231 if (argc - i < 2)
232 usage ();
233
234 /* Set initial values. */
235
236 verbose = FALSE; silent = FALSE; cmd = 0;
237
238 /* Skip a leading - character, it's optional. */
239
240 s = argv[i++];
241 if (*s == '-')
242 ++s;
243
244 /* Parse the command. */
245
246 while (*s != 0)
247 {
248 new_cmd = 0;
249 switch (*s)
250 {
251 case 'v':
252 verbose = TRUE;
253 break;
254 case 'c':
255 silent = TRUE;
256 break;
257 case 's':
258 if (cmd == 0)
259 new_cmd = 's';
260 break;
261 case 'd':
262 case 'r':
263 case 't':
264 case 'x':
265 new_cmd = *s;
266 break;
267 case 'q':
268 new_cmd = 'r';
269 break;
270 case 'u':
271 if (cmd == 0)
272 new_cmd = 'r';
273 break;
274 case 'l':
275 case 'o':
276 break;
277 default:
278 usage ();
279 }
280 ++s;
281 if (new_cmd != 0)
282 {
283 if (cmd != 0)
284 usage ();
285 cmd = new_cmd;
286 }
287 }
288
289 /* Complain if no command letter was given. */
290
291 if (cmd == 0)
292 usage ();
293
294 /* The s command is a no-op. */
295
296 if (cmd == 's')
297 return 0;
298
299 /* Add the .lib default extension to the library name. The result
300 is in ext_fname. */
301
302 _strncpy (ext_fname, argv[i++], sizeof (ext_fname) - 4);
303 _defext (ext_fname, "lib");
304
305 /* Initialize file names and OMFLIB descriptors. */
306
307 lib_fname = ext_fname;
308 lib = NULL;
309 new_fname = NULL;
310 new_lib = NULL;
311
312 /* Make create non-zero iff we have to create a new library file. */
313
314 create = (cmd == 'r' && access (lib_fname, 4) != 0);
315
316 /* The r and d commands create a library file if it doesn't exist.
317 If it does exist, a backup file is created. */
318
319 if (cmd == 'r' || cmd == 'd')
320 {
321 if (create)
322 {
323 if (!silent)
324 printf ("Creating library file `%s'\n", lib_fname);
325 new_fname = lib_fname;
326 lib_fname = NULL;
327 }
328 else
329 {
330 _strncpy (bak_fname, lib_fname, sizeof (bak_fname) - 4);
331 _remext (bak_fname);
332 _defext (bak_fname, "bak");
333 if (_fncmp (lib_fname, bak_fname) == 0)
334 {
335 fprintf (stderr, "Cannot update backup file\n");
336 exit (1);
337 }
338 remove (bak_fname);
339 if (rename (lib_fname, bak_fname) != 0)
340 {
341 perror (lib_fname);
342 exit (2);
343 }
344 new_fname = lib_fname;
345 lib_fname = bak_fname;
346 }
347 }
348
349 /* If no new library file is to be created, the library file is
350 supposed to exist. Open it. */
351
352 if (!create)
353 {
354 lib = omflib_open (lib_fname, error);
355 if (lib == NULL)
356 {
357 fprintf (stderr, "emxomfar: %s: %s\n", lib_fname, error);
358 exit (2);
359 }
360 }
361
362 /* Create the output library for the r and d commands. */
363
364 if (cmd == 'r' || cmd == 'd')
365 {
366 new_lib = omflib_create (new_fname, page_size, error);
367 if (new_lib == NULL)
368 {
369 fprintf (stderr, "emxomfar: %s: %s\n", new_fname, error);
370 exit (2);
371 }
372 }
373
374 /* Close files when done or when aborting. */
375
376 atexit (cleanup);
377
378 /* Write header of new library. */
379
380 if (cmd == 'r' || cmd == 'd')
381 {
382 if (omflib_header (new_lib, error) != 0)
383 {
384 fprintf (stderr, "emxomfar: %s\n", error);
385 exit (2);
386 }
387 }
388
389 if (i >= argc && !(cmd == 'r' || cmd == 'd'))
390 {
391
392 /* No arguments specified for the t and x commands: Apply
393 do_mod() to all modules of the library. */
394
395 n = omflib_module_count (lib, error);
396 if (n == -1)
397 {
398 fprintf (stderr, "emxomfar: %s\n", error);
399 exit (2);
400 }
401 for (i = 0; i < n; ++i)
402 {
403 if (omflib_module_info (lib, i, name, &page, error) != 0)
404 fprintf (stderr, "emxomfar: %s\n", error);
405 else
406 do_mod (name);
407 }
408 }
409 else
410 {
411 /* Apply do_mod() to all modules given on the command line. */
412
413 while (i < argc)
414 {
415 if (!(cmd == 'd' && strcmp (argv[i], "__.SYMDEF") == 0))
416 do_mod (argv[i]);
417 ++i;
418 }
419 }
420
421 /* Copy all the unmodified modules of the original library to the
422 new library. */
423
424 if (cmd == 'r' || cmd == 'd')
425 {
426 if ((!create && omflib_copy_lib (new_lib, lib, error) != 0)
427 || omflib_finish (new_lib, error) != 0
428 || omflib_close (new_lib, error) != 0)
429 {
430 fprintf (stderr, "emxomfar: %s\n", error);
431 exit (2);
432 }
433 new_lib = NULL; new_fname = NULL;
434 }
435
436 /* Close the source library. */
437
438 if (lib != NULL && omflib_close (lib, error) != 0)
439 fprintf (stderr, "emxomfar: %s\n", error);
440 return 0;
441}
Note: See TracBrowser for help on using the repository browser.