home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
g
/
gtak212.zip
/
1.10
/
ak_dir.c
next >
Wrap
C/C++ Source or Header
|
1992-10-29
|
6KB
|
226 lines
/*****************************************************************************
* $Id: ak_dir.c,v 1.3 1992/10/29 10:26:35 ak Exp $
*****************************************************************************
* $Log: ak_dir.c,v $
* Revision 1.3 1992/10/29 10:26:35 ak
* *** empty log message ***
*
* Revision 1.2 1992/09/12 15:57:09 ak
* - Usenet patches for GNU TAR 1.10
* - Bugfixes and patches of Kai Uwe Rommel:
* filename conversion for FAT
* EMX 0.8e
* -0..1 alias for a: b:
* -2..7 alias for +++TAPE$x
*
* Revision 1.1 1992/09/02 20:07:32 ak
* Initial revision
*
*****************************************************************************/
static char *rcsid = "$Id: ak_dir.c,v 1.3 1992/10/29 10:26:35 ak Exp $";
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "tar.h"
#include "port.h"
#include "rmt.h"
extern union record *head; /* Points to current tape header */
extern struct stat hstat; /* Stat struct corresponding */
extern int head_standard; /* Tape header is in ANSI format */
/*
* Random archive access.
*/
void
seek_exec(do_something, name, vol, voloff, rec, skip)
void (*do_something)();
char *name;
int vol;
long voloff, rec, skip;
{
long r;
static int error_flag;
extern int volno;
extern long baserec;
static long lastseek = - 1, lastend;
if (f_multivol) {
if (vol != volno) {
/* next volume */
close_archive(1);
sprintf(ar_file + strlen(ar_file) - 3, "%03d", vol);
open_archive(1);
ar_last = ar_record = ar_block;
baserec = 0;
volno = vol;
}
}
if (voloff + rec != lastseek) {
lastseek = voloff + rec;
msg("Seek to physical block %ld", voloff + rec);
r = rmtlseek(archive, (voloff + rec) * RECORDSIZE,
_isrmt(archive) ? 3 : 0);
ar_last = ar_record = ar_block;
baserec = rec;
if (r < 0) {
if (vol)
msg_perror("Seek error on %s, volume %d record %ld",
ar_file, vol, rec);
else
msg_perror("Seek error on %s, record %ld",
ar_file, rec);
if (++error_flag > 10) {
msg("Too many errors, quitting.");
exit(EX_BADARCH);
}
return;
}
}
else
skip -= lastend;
/* skip alignment blocks */
if (skip) {
long record_skip = skip % blocking;
long block_skip = skip - record_skip;
/* msg("Skip over %ld logical blocks", skip); */
if (block_skip) {
r = rmtlseek(archive, block_skip * RECORDSIZE, 1);
baserec += block_skip;
}
while (record_skip--)
userec(findrec());
}
if (read_header() == 1) {
/* We should decode next field (mode) first... */
/* Ensure incoming names are null terminated. */
head->header.name[NAMSIZ-1] = '\0';
/* Handle the archive member */
(*do_something)();
lastend = baserec - rec + ar_record - ar_block;
} else {
if (vol)
msg("File %s volume %d record %ld has invalid header, wrong map file?",
name, vol, rec);
else
msg("File %s record %ld has invalid header, wrong map file?",
name, rec);
if (++error_flag > 10) {
msg("Too many errors, quitting.");
exit(EX_BADARCH);
}
}
}
/*
* Main loop for random access.
*/
void
seek_and(do_something)
void (*do_something)();
{
extern FILE *map_file;
struct name *nlp;
char line[60 + FILENAME_MAX];
long voloff, offset, skip;
char *p;
int len, volume;
#if 0
struct Volmap {
long base; /* physical base record no */
short ctrl; /* no of inserted control records */
short num; /* volume no */
struct Volmap *prev; /* previous volume */
} *volmap, *q;
#endif
name_gather(); /* Gather all the names */
open_archive(1); /* Open for reading */
volume = voloff = 0;
rewind(map_file);
while (fgets(line, 60 + FILENAME_MAX, map_file)) {
char *name = line + strlen(line);
char *key = strtok(line, " \t");
char *arg = key ? strtok(NULL, ": \t\r\n") : NULL;
char *mode = arg ? strtok(NULL, " \t") : NULL;
char *q;
offset = arg ? strtol(arg, &q, 0) : 0;
skip = (q && *q == '+') ? strtol(q+1, &q, 0) : 0;
if (strncmp(key, "vol", 3) == 0) {
/* base address of tape file */
voloff = offset;
continue;
}
if (key[0] == 'V') {
/* tape number */
volume = atoi(key+1);
continue;
}
if (strcmp(key, "blk") == 0) {
extern long tapeblock;
voloff = 0;
offset = offset * tapeblock / RECORDSIZE;
} else if (strncmp(key, "rec", 3) != 0)
continue;
if (mode[0] == 'M')
continue;
/* get file name from record line -- skip "(..)" descr */
while (isspace(*(name-1)))
--name;
if (mode[0] == 'A' && *(name-1) == ')')
while (*--name != '(')
;
while (isspace(*(name-1)))
--name;
*name = '\0';
while (!isspace(*(name-1)))
--name;
len = strlen(name);
/* look if name is mentioned in command line */
for (nlp = namelist; nlp; nlp = nlp->next) {
/* fast check for first character */
if (nlp->firstch && nlp->name[0] != name[0])
continue;
/* regular expression? */
if (nlp->regexp) {
if (wildmat(name, nlp->name))
goto match;
continue;
}
/* plain name */
if (nlp->length <= len
&& (name[nlp->length] == '\0'
|| name[nlp->length] == '/')
#ifdef MSDOS
&& strnicmp(name, nlp->name, nlp->length) == 0)
#else
&& strncmp(name, nlp->name, nlp->length) == 0)
#endif
goto match;
continue;
match: seek_exec(do_something, name, volume, voloff, offset, skip);
if (mode[0] != 'A')
nlp->found = 1;
}
}
close_archive(1);
names_notfound(); /* Print names not found */
}