summaryrefslogtreecommitdiff
path: root/arscan.c
diff options
context:
space:
mode:
Diffstat (limited to 'arscan.c')
-rw-r--r--arscan.c205
1 files changed, 187 insertions, 18 deletions
diff --git a/arscan.c b/arscan.c
index e63659e..9cf746b 100644
--- a/arscan.c
+++ b/arscan.c
@@ -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