diff options
Diffstat (limited to 'binutils-1.9/ranlib.c')
| -rw-r--r-- | binutils-1.9/ranlib.c | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/binutils-1.9/ranlib.c b/binutils-1.9/ranlib.c new file mode 100644 index 0000000..91e72d1 --- /dev/null +++ b/binutils-1.9/ranlib.c @@ -0,0 +1,241 @@ +/* Dummy ranlib program for GNU. + All it does is `ar rs LIBRARY' for each library specified. + + Copyright (C) 1989, 1990 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <ar.h> +#include <sys/types.h> +#include <sys/file.h> +#include <stdio.h> +#include <fcntl.h> +#include "getopt.h" +#include "signame.h" + +#ifndef L_SET +#define L_SET 0 +#define L_INCR 1 +#endif + +#ifndef X_OK +#define X_OK 1 +#endif + +#ifdef USG +#define bzero(s, n) (memset ((s), 0, (n))) +#define gettimeofday(TV,TZ) (time (TV)) +#define seconds(TV) TV +long time(); +#else +#define seconds(TV) TV.tv_sec +#include <sys/time.h> +#endif + +#ifdef USG +#define vfork fork +#endif + +void touch_symdefs (); +void usage (); + +/* The makefile generates a -D switch to define AR_PROG + as the location of the GNU `ar' program. */ +char *prog = AR_PROG; + +/* The first place we look for `ar', before trying `prog'. */ +char *prog_pref = "/usr/local/gnubin/ar"; + +/* The name this program was run with. */ +char *program_name; + +void +main (argc, argv) + int argc; + char **argv; +{ + static int touch = 0, verbose = 0; + static char short_opts[] = "tv"; + static struct option long_opts[] = + { + { "touch", 0, &touch, 0 }, + { "verbose", 0, &verbose, 0 }, + { 0, 0, 0, 0 } + }; + register int c; + char *args; + int longind; + char *ar_program; + + program_name = argv[0]; + + while ((c = getopt_long (argc, argv, short_opts, long_opts, &longind)) + != EOF) + switch (c) + { + case 't': + touch = 1; + break; + + case 'v': + verbose = 1; + break; + + default: + usage (); + } + + if (optind == argc) + usage (); + + if (access (prog_pref, X_OK) == 0) + ar_program = prog_pref; + else + ar_program = prog; + + args = verbose ? "rsv" : "rs"; + + if (touch) + touch_symdefs (argc - optind, argv + optind); + else + { + register int i; + for (i = optind; i < argc; ++i) + { + int pid; + + if (verbose) + printf ("%s %s %s\n", ar_program, args, argv[i]); + + fflush (stdout); + fflush (stderr); + + pid = vfork (); + if (pid < 0) + { + fprintf (stderr, "%s: can not ", program_name); + perror ("vfork"); + } + else if (pid == 0) + { + /* Child side. */ + execl (ar_program, ar_program, args, argv[i], 0); + fprintf (stderr, "%s: can not run ", program_name); + perror (ar_program); + exit (1); + } + else + { + /* Parent side. */ + int status; + if (wait (&status) != pid) + { + fprintf (stderr, "%s: interrupted during ", program_name); + perror ("wait"); + } + if ((status & 0x7f) != 0) + { + psignal (status & 0x7f, ar_program); + exit (1); + } + else if (((status & 0xff00) >> 8) != 0) + exit ((status & 0xff00) >> 8); + } + } + } + + exit (0); +} + +/* "touch" the archive files listed in LARGV, containing LARGC elements. + Find the first symdef member in them and update the date to the + current one. */ + +void +touch_symdefs (largc, largv) + int largc; + char **largv; +{ +#ifdef USG + long tv; +#else + struct timeval tv; + struct timezone tz; +#endif + struct ar_hdr archive_header; + int i, rr; + + gettimeofday (&tv, &tz); + + while (largc--) + { + int fd = open (*largv, O_RDWR); + + if (fd < 0) + { + fprintf (stderr, "%s: can not open `%s' for ", program_name, *largv); + perror ("read/write"); + largv++; + continue; + } + + lseek (fd, SARMAG, L_SET); + + rr = read (fd, &archive_header, sizeof (archive_header)); + + /* In the general case this loop would be sped up by buffering, + but in almost all cases the symdef will be the first member, so + I'm not going to bother. */ + + while (rr == sizeof (archive_header)) + { + if (!strncmp ("__.SYMDEF", archive_header.ar_name, + sizeof ("__.SYMDEF") - 1)) + { + bzero ((char *) archive_header.ar_date, + sizeof (archive_header.ar_date)); + + sprintf (archive_header.ar_date, "%d", seconds (tv)); + + for (i = 0; i < sizeof archive_header.ar_date; i++) + if (archive_header.ar_date[i] == '\0') + archive_header.ar_date[i] = ' '; + + lseek (fd, - rr, L_INCR); + write (fd, &archive_header, sizeof (archive_header)); + close (fd); + break; + } + + lseek (fd, atoi (archive_header.ar_size), L_INCR); + rr = read (fd, &archive_header, sizeof (archive_header)); + } + + if (rr != sizeof (archive_header)) + /* We reached the end of the file. */ + fprintf (stderr, "%s: can not find `__.SYMDEF' member in `%s'\n", + program_name, *largv); + + largv++; + } +} + +void +usage () +{ + fprintf (stderr, "Usage: %s [-tv] [+touch] [+verbose] archive...\n", + program_name); + exit (1); +} |
