/* 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 #include #include #include #include #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 #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); }