misc.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1987-2012 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Glenn Fowler
* AT&T Bell Laboratories
*
* pax miscellaneous support
*/
#include "pax.h"
#include <dlldefs.h>
#include <sfdisc.h>
#include <tmx.h>
static Format_t*
scan(void)
{
void* dll;
{
{
else
}
else
}
}
/*
* format list iterator
* fp=0 for first element
* dll format scan kicked in when static formats exhausted
*/
{
if (!fp)
return formats;
{
}
return fp;
}
/*
* return format given name
*/
{
name = FMT_DEFAULT;
fp = 0;
if (!strcasecmp(name, fp->name) || fp->match && strgrpmatch(name, fp->match, NiL, 0, STR_ICASE|STR_LEFT|STR_RIGHT))
return fp;
if (must)
return 0;
}
/*
* path name strcmp()
*/
static int
pathcmp(register const char* s, register const char* t)
{
register int sc;
register int tc;
for (;;)
{
tc = *t++;
if (!(sc = *s++))
return tc ? -1 : 0;
{
return 1;
if (sc == '/')
return -1;
}
}
}
/*
* check base archive ordering
*/
static void
{
}
/*
* check f with patterns given on cmd line
*/
int
{
register Member_t* d;
int linked = 0;
int c;
Tv_t t;
return 0;
{
}
{
static char fmt[2];
return 0;
}
{
linked = 1;
return 0;
nospace();
d->uncompressed = f->uncompressed;
if (!(d->info = (File_t*)memdup(f, sizeof(File_t))) || !(d->info->st = (struct stat*)memdup(f->st, sizeof(struct stat))))
nospace();
return 0;
}
return 0;
{
/* keep */;
return 0;
return 0;
else
return 0;
}
return 0;
if (!linked)
{
{
nospace();
d->uncompressed = f->uncompressed;
}
}
{
register int n;
register int m;
for (;;)
{
else
{
break;
}
{
break;
}
if (!m)
break;
{
{
}
else
{
{
{
{
else
listentry(f);
}
}
else
listentry(f);
}
}
}
}
}
return 1;
}
/*
* verify action on file
*
* EOF exit
* NULL skip file
* . keep file
* <else> rename file
*/
int
{
register char* name;
if (!prompt)
{
return 0;
{
case IN:
prompt = "Read";
break;
case OUT:
prompt = "Write";
break;
default:
prompt = "Pass";
break;
}
else
prompt = "Rename";
}
{
finish(2);
}
{
{
return 0;
}
}
switch (*name)
{
case 0:
return 0;
case '.':
if (!*(name + 1))
break;
/*FALLTHROUGH*/
default:
break;
}
return 1;
}
/*
* no dos in our pathnames
*/
void
{
register char* s;
{
s = f->name;
{
if (*(s += 2) == '\\' || *s == '/')
s++;
f->name = s;
}
for (; *s; s++)
if (*s == '\\')
*s = '/';
}
}
/*
* check for file name mapping
* static data possibly returned
* two simultaneous calls supported
*/
char*
{
char* to;
char* from;
File_t f;
int n;
{
}
{
nospace();
break;
}
else if (n != REG_NOMATCH)
if (state.local && (*to == '/' || *to == '.' && *(to + 1) == '.' && (!*(to + 2) || *(to + 2) == '/')))
{
{
return f.name;
}
to = "";
}
return to;
}
typedef struct
{
#define TYPE_mode 1
#define TYPE_time 2
/*
* sfkeyprintf() lookup
*/
static int
{
char* s = 0;
Sflong_t n = 0;
Time_t t = TMX_NOTIME;
int type = 0;
int k;
char* e;
static const char fmt_time[] = "time=%?%l";
static const char fmt_mode[] = "mode";
{
{
return 0;
nospace();
}
{
nospace();
nospace();
}
else
{
case OPT_atime:
t = tmxgetatime(st);
break;
case OPT_charset:
s = "ASCII";
break;
case OPT_ctime:
t = tmxgetctime(st);
break;
case OPT_delta_op:
sfsprintf(s = fmtbuf(32), 32, "%c%02d.%1d%%", f->delta.op ? f->delta.op : 'c', k, (int)((st->st_size * 1000) / f->uncompressed) % 10);
else
{
case 0:
case DELTA_pass:
return 0;
case DELTA_create:
s = "create";
break;
case DELTA_delete:
s = "delete";
break;
case DELTA_update:
s = "update";
break;
case DELTA_verify:
s = "verify";
break;
default:
break;
}
break;
case OPT_device:
else
return 0;
break;
case OPT_devmajor:
break;
case OPT_devminor:
break;
case OPT_dir:
{
nospace();
}
else
s = ".";
break;
case OPT_entry:
break;
case OPT_environ:
return 0;
break;
case OPT_gname:
if (f->gidname)
{
s = f->gidname;
else
break;
}
/*FALLTHROUGH*/
case OPT_gid:
else
break;
case OPT_ino:
break;
case OPT_linkop:
switch (f->linktype)
{
case HARDLINK:
s = "==";
break;
case SOFTLINK:
s = "->";
break;
default:
return 0;
}
break;
case OPT_linkpath:
return 0;
s = f->linkpath;
break;
case OPT_mark:
s = "=";
s = "@";
s = "/";
s = "|";
s = "=";
s = "$";
s = "*";
else
return 0;
break;
case OPT_mode:
break;
case OPT_mtime:
t = tmxgetmtime(st);
break;
case OPT_name:
s++;
else
s = f->name;
break;
case OPT_nlink:
break;
case OPT_path:
s = f->name;
break;
case OPT_pid:
break;
case OPT_release:
s = release();
break;
case OPT_sequence:
else
break;
case OPT_size:
n = f->linkpathsize - 1;
else if (f->uncompressed)
n = f->uncompressed;
else
break;
case OPT_tmp:
{
nospace();
}
else
s = ".";
break;
case OPT_uname:
if (f->uidname)
{
s = f->uidname;
else
break;
}
/*FALLTHROUGH*/
case OPT_uid:
else
break;
default:
{
return 0;
else if (k > 0)
break;
}
return 0;
break;
}
}
else
{
op = 0;
{
case 'd':
if (!op)
s = f->name;
if (e = strrchr(s, '/'))
{
nospace();
}
else
s = ".";
*ps = s;
return 1;
case 'f':
break;
case 'n':
return 1;
case 'p':
return 1;
}
}
{
case 'D':
else if (!op)
s = " ";
else
{
*pn = n;
return 1;
}
break;
case 'L':
{
if (!op)
s = f->name;
nospace();
break;
}
/*FALLTHROUGH*/
case 'F':
if (!op)
s = f->name;
if (e = strrchr(s, '/'))
s = e + 1;
break;
case 'M':
if (!op)
s = fmtmode(n, 1);
break;
case 'T':
if (!arg)
arg = "%b %e %H:%M %Y";
if (!op)
{
t = tmxgetmtime(st);
}
{
t = TMX_NOTIME;
}
break;
default:
if (s)
*ps = s;
{
{
arg += 5;
{
t = TMX_NOTIME;
}
}
}
else
*pn = n;
return 1;
}
*ps = s;
return 1;
}
/*
* set up lookup() handle and call sfkeyprintf()
*/
int
{
}
/*
* list entry information based on state.drop, state.list and state.verbose
*/
void
{
int n;
int p;
int i;
int j;
int k;
char* s;
char* e;
{
{
for (s = f->name; *s; s++)
if (s[0] == ' ' && s[1] == '-' && s[2] == '-' && s[3] == ' ')
break;
if (*s)
{
{
}
return;
}
p = 99;
nospace();
{
{
e = "*";
}
else
e = "";
j = n + METER_width;
k = 0;
i = sizeof(bar) - 1;
n = 0;
while (n < i)
bar[n++] = '*';
bar[n++] = ' ';
bar[n] = 0;
}
else
sleep(1);
}
{
{
}
else
{
}
}
else
}
}
/*
* prepare patterns for match()
*/
void
initmatch(char** v)
{
register char* s;
register char** a;
Pattern_t* p;
size_t n;
size_t m;
m = 0;
a = v;
while (*a)
m += strlen(*a++) + 1;
n = a - v + 1;
nospace();
s = (char*)(p + n);
for (a = v; *a; a++, p++)
{
}
}
/*
* determine if file s matches input patterns
*/
int
match(register char* s)
{
register Pattern_t* p;
int n;
return state.matchsense;
{
for (n = 0; p->pattern; p++)
{
{
return 1;
}
else if (p->directory)
p->directory = 0;
{
p->matched = 1;
return 1;
}
else
n = 1;
}
if (!n)
finish(0);
}
else
for (; p->pattern; p++)
return state.matchsense;
return !state.matchsense;
}
/*
* return 1 if p is a directory prefix of s
*/
int
{
if (*p == '.' && !*(p + 1) && *s != '/' && (*s != '.' || *(s + 1) != '.' || *(s + 2) && *(s + 2) != '/'))
return !proper;
if (*p == '/' && !*(p + 1))
return *s == '/';
while (*p)
if (*p++ != *s++)
return 0;
return *s == '/' || !proper && !*s;
}
/*
* allocate and copy a tmp string
* a!=0 for lifetime of a
* f!=0 for lifetime of f
*/
char*
{
if (!z)
{
if (!s)
return 0;
z = strlen(s);
}
z++;
if (z > v->size)
{
nospace();
}
if (s)
{
v->string[z - 1] = 0;
}
return v->string;
}
/*
* out of space panic
*/
void
nospace(void)
{
}
/*
* if current file cannot fit completely in current archive
* then bump it to another volume
*/
void
{
off_t n;
{
else
{
putprologue(ap, 0);
}
}
}
/*
* verify that compress undo command exists
* alternate undotoo checked if undo not found
*/
void
{
{
}
}