diff options
Diffstat (limited to 'arscan.c')
-rw-r--r-- | arscan.c | 205 |
1 files changed, 187 insertions, 18 deletions
@@ -1,19 +1,19 @@ /* Library function for scanning an archive file. - Copyright (C) 1987, 89, 91, 92, 93, 94, 95 Free Software Foundation, Inc. +Copyright (C) 1987,89,91,92,93,94,95,97 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 2, or (at your option) - any later version. +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 2, 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. +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. */ +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 "make.h" @@ -25,6 +25,171 @@ #ifndef NO_ARCHIVES +#ifdef VMS +#include <lbrdef.h> +#include <mhddef.h> +#include <credef.h> +#include <descrip.h> +#include <ctype.h> +#if __DECC +#include <unixlib.h> +#include <lbr$routines.h> +#endif + +#define uppercasify(str) {char *str1; for (str1 = str; *str1; str1++) *str1 = _toupper(*str1);} + +static void *VMS_lib_idx; + +static char *VMS_saved_memname; + +static time_t VMS_member_date; + +static long int (*VMS_function) (); + +static int +VMS_get_member_info (module, rfa) + struct dsc$descriptor_s *module; + unsigned long *rfa; +{ + int status, i; + long int fnval; + + time_t val; + + static struct dsc$descriptor_s bufdesc = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; + + struct mhddef *mhd; + char filename[128]; + + bufdesc.dsc$a_pointer = filename; + bufdesc.dsc$w_length = sizeof (filename); + + status = lbr$set_module (&VMS_lib_idx, rfa, &bufdesc, + &bufdesc.dsc$w_length, 0); + if (! status) + { + error ("lbr$set_module failed to extract module info, status = %d", + status); + + lbr$close (&VMS_lib_idx); + + return 0; + } + + mhd = (struct mhddef *) filename; + + val = decc$fix_time (&mhd->mhd$l_datim); + + for (i = 0; i < module->dsc$w_length; i++) + filename[i] = _tolower (module->dsc$a_pointer[i]); + + filename[i] = '\0'; + + VMS_member_date = (time_t) -1; + + fnval = + (*VMS_function) (-1, filename, 0, 0, 0, 0, val, 0, 0, 0, + VMS_saved_memname); + + if (fnval) + { + VMS_member_date = fnval; + return 0; + } + else + return 1; +} + +/* Takes three arguments ARCHIVE, FUNCTION and ARG. + + Open the archive named ARCHIVE, find its members one by one, + and for each one call FUNCTION with the following arguments: + archive file descriptor for reading the data, + member name, + member name might be truncated flag, + member header position in file, + member data position in file, + member data size, + member date, + member uid, + member gid, + member protection mode, + ARG. + + NOTE: on VMS systems, only name, date, and arg are meaningful! + + The descriptor is poised to read the data of the member + when FUNCTION is called. It does not matter how much + data FUNCTION reads. + + If FUNCTION returns nonzero, we immediately return + what FUNCTION returned. + + Returns -1 if archive does not exist, + Returns -2 if archive has invalid format. + Returns 0 if have scanned successfully. */ + +long int +ar_scan (archive, function, arg) + char *archive; + long int (*function) (); + long int arg; +{ + char *p; + + static struct dsc$descriptor_s libdesc = + { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; + + unsigned long func = LBR$C_READ; + unsigned long type = LBR$C_TYP_UNK; + unsigned long index = 1; + + int status; + + status = lbr$ini_control (&VMS_lib_idx, &func, &type, 0); + + if (! status) + { + error ("lbr$ini_control failed with status = %d",status); + return -2; + } + + libdesc.dsc$a_pointer = archive; + libdesc.dsc$w_length = strlen (archive); + + status = lbr$open (&VMS_lib_idx, &libdesc, 0, 0, 0, 0, 0); + + if (! status) + { + error ("unable to open library `%s' to lookup member `%s'", + archive, (char *)arg); + return -1; + } + + VMS_saved_memname = (char *)arg; + + /* For comparison, delete .obj from arg name. */ + + p = rindex (VMS_saved_memname, '.'); + if (p) + *p = '\0'; + + VMS_function = function; + + lbr$get_index (&VMS_lib_idx, &index, VMS_get_member_info, 0); + + /* Undo the damage. */ + if (p) + *p = '.'; + + lbr$close (&VMS_lib_idx); + + return VMS_member_date > 0 ? VMS_member_date : 0; +} + +#else /* !VMS */ + /* SCO Unix's compiler defines both of these. */ #ifdef M_UNIX #undef M_XENIX @@ -203,7 +368,7 @@ ar_scan (archive, function, arg) (void) close (desc); return -2; } - + name[name_len] = 0; sscanf (member_header.ar_date, "%12ld", &dateval); @@ -277,7 +442,7 @@ ar_scan (archive, function, arg) && name[2] == '/') { int namesize = atoi (name + 3); - + name = (char *) alloca (namesize + 1); nread = read (desc, name, namesize); if (nread != namesize) @@ -351,7 +516,7 @@ ar_scan (archive, function, arg) (void) close (desc); return -2; } - + /* The names are separated by newlines. Some formats have a trailing slash. Null terminate the strings for convenience. */ @@ -365,7 +530,7 @@ ar_scan (archive, function, arg) clear[-1] = '\0'; } } - + is_namemap = 0; } @@ -379,6 +544,7 @@ ar_scan (archive, function, arg) close (desc); return 0; } +#endif /* !VMS */ /* Return nonzero iff NAME matches MEM. If TRUNCATED is nonzero, MEM may be truncated to @@ -426,7 +592,7 @@ ar_name_equal (name, mem, truncated) } #else /* AIX or APOLLO. */ - +#ifndef VMS if (truncated) { #ifdef AIAMAG @@ -435,7 +601,7 @@ ar_name_equal (name, mem, truncated) #else struct ar_hdr hdr; return !strncmp (name, mem, - sizeof (hdr.ar_name) - + sizeof (hdr.ar_name) - #if !defined (__hpux) && !defined (cray) 1 #else @@ -444,12 +610,14 @@ ar_name_equal (name, mem, truncated) ); #endif } +#endif /* !VMS */ return !strcmp (name, mem); #endif } +#ifndef VMS /* ARGSUSED */ static long int ar_member_pos (desc, mem, truncated, @@ -532,6 +700,7 @@ ar_member_touch (arname, memname) errno = i; return -3; } +#endif #ifdef TEST |