home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-387-Vol-3of3.iso
/
d
/
dshar116.zip
/
SETARGS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-11
|
9KB
|
439 lines
/* setargs.c dshar Ver1.16 nide@nara-wu.ac.jp */
#define SETARGS_MAIN
#include <stdio.h>
#include <ctype.h>
#ifdef UNIX
# include <fcntl.h>
# include <sys/types.h>
# include <sys/stat.h>
#endif
#include <signal.h>
#include "common.h"
#define RESPF '@'
static void addarg(), addindarg(), addindfarg(), addfarg();
static void adddirarg(), add1arg();
static char *strsave(), *strpathcatsave(), *strdircatsave();
static int newac, newavsize;
static char **newav;
char *emalloc(p, i)
register char *p;
register unsigned int i;
{
if(NULL == (p = (char *)(p == NULL ? malloc(i) : realloc(p, i))))
(perror(NULL), exit(1));
return p;
}
void setargs(acp, avp, passcnt)
int *acp, passcnt;
char **avp[];
{
register int ac = *acp;
register char **av = *avp;
newavsize = ac, newac = 0;
newav = (char **)emalloc(NULL, (newavsize + 1) * sizeof(char *));
ac--, add1arg(unixname(*av++));
while(passcnt-- && ac--) add1arg(*av++);
while(ac--) addarg(*av++);
newav[newac] = NULL;
if(newavsize > newac) newav = (char **)
emalloc((char *)newav, (newac + 1) * sizeof(char *));
*acp = newac, *avp = newav;
}
#ifdef UNIX
FILE *piperdopen(cmd, av, inf)
register char *cmd, **av;
FILE *inf;
{
int pipefd[2];
if(-1 == pipe(pipefd)) (perror(NULL), exit(1));
fflush(stdout); /* must make output buffer empty */
switch(fork()){
case 0: /* child */
fclose(stdout);
if(inf == NULL){
/* stdin not yet closed... */
if(NULL == freopen("/dev/null", "r", stdin))
(perror(NULL), exit(1));
} else { /* assuming inf != stdin */
fclose(stdin);
if(0 != dup(fileno(inf))) (perror(NULL), exit(1));
fclose(inf);
}
if(1 != dup(pipefd[1])) (perror(NULL), exit(1));
close(pipefd[0]), close(pipefd[1]);
execvp(cmd, av);
/* through to perror */
case -1:
perror(NULL), exit(1);
default:
if(inf != NULL) fclose(inf);
close(pipefd[1]);
return fdopen(pipefd[0], "r");
}
}
static isdir(name)
register char *name;
{
struct stat statbuf;
return(0 == stat(name, &statbuf) &&
S_IFDIR == (statbuf . st_mode & S_IFMT));
}
static FILE *dirfindopen(s)
register char *s;
{
static char *av[] = {
"find", NULL, "-type", "f", "-print", NULL
};
av[1] = s;
return execrdopen(*av, av);
/* must call wait() afterward */
}
#endif /* UNIX */
static isdirarg(s)
register char *s;
{
for(; *s && s[1]; s++) if(iskanjipos(s)) s++;
return isDelim(*s);
}
static isdotdir(s)
register char *s;
{
#define isdotonlydir(s) \
(*(s) == '.' && (!*((s) + 1) || *((s) + 1) == '.' && !*((s) + 2)))
if(isdotonlydir(s)) return 1;
for(; *s; s++){
if(iskanjipos(s)){
s++;
continue;
}
if(isDelim(*s) && isdotonlydir(s + 1)) return 1;
}
return 0;
}
static wropenchk(s)
register char *s;
{
register FILE *tmpf;
int flag = 0;
signal(SIGINT, SIG_IGN);
#ifdef DEBUG
fprintf(stderr, "Test opening '%s'!\n", s);
#endif
if(NULL != (tmpf = fopen(s, "r"))){
fclose(tmpf);
flag = 1;
} else
if(NULL != (tmpf = fopen(s, "w"))){
fclose(tmpf), unlink(s);
flag = 1;
}
signal(SIGINT, SIG_DFL);
return flag;
}
is8bit(s)
register char *s;
{
for(; *s; s++) if(!isascii(*s)) return 1;
return 0;
}
have8bit(ac, av)
register int ac;
register char *av[];
{
for(; ac; ac--, av++) if(is8bit(*av)) return 1;
return 0;
}
isjapan() /* uses ShiftJIS? */
{
#ifndef UNIX
static flag = -1;
register char *tmpdir, *tmpname, *tmpbase = "_tmp$$\201\\.$$$";
if(flag < 0){
flag = 0;
if(NULL != (tmpdir = getenv("TMP")) && !is8bit(tmpdir)){
/* if $TMP contains 8bit code, strpathcatsave()
calls isjapan() recursively! */
tmpname = strpathcatsave(tmpdir, tmpbase);
if(wropenchk(tmpname)) flag = 1;
free(tmpname);
}
if(flag != 1 && wropenchk(tmpbase)) flag = 1;
}
return flag;
#else
return 0; /* not supported */
#endif
}
iskanjipos(s)
register char *s;
{
if(!iskanji(*s) || !isjapan()) return 0;
if(!s[1]){
fputs("Incomplete KANJI filename\n", stderr);
exit(1);
}
return 1;
}
char *nameconv(s, mode)
register char *s;
register int mode;
/* 0: MS-DOS -> UNIX, 1: UNIX -> MS-DOS. Upper -> lower also.
Length is not changed. Overwrites the resulting string on each call */
{
#define MODEMAX 2
static char *p[MODEMAX] = {NULL, NULL};
static int psize[MODEMAX] = {0, 0};
if(strlen(s) >= psize[mode])
p[mode] = emalloc(p[mode], (psize[mode] = strlen(s) + 1));
for(s = strcpy(p[mode], s); *s; s++){
if(iskanjipos(s)){
s++;
continue;
}
#ifndef UNIX
if(is_upper(*s)) *s = tolower(*s); else
#endif
switch(mode){
case 0:
if(*s == '\\') *s = '/';
break;
case 1:
if(*s == '/') *s = '\\';
break;
}
}
return p[mode];
}
static char *strsave(s)
register char *s;
{
return strcpy(emalloc(NULL, strlen(s) + 1), s);
}
static char *strpathcatsave(s, r)
register char *s;
char *r;
{
register char *p;
int notadd_delim;
notadd_delim = !*s || isdirarg(s);
p = emalloc(NULL, strlen(s) + !notadd_delim + strlen(r) + 1);
return(sprintf(p, "%s%s%s", s, DELIM + notadd_delim, r), p);
}
static char *strdircatsave(s, r)
char *s, *r;
{
register char *p, *end = NULL;
for(p = s; *p && p[1]; p++){
if(iskanjipos(p)) p++;
else if(isDelim(*p)) end = p;
}
if(end++ == NULL){
return strsave(r);
} else {
p = emalloc(NULL, (end - s) + strlen(r) + 1);
return(strcpy(p + (end - s), r), strncpy(p, s, end - s));
}
}
static fnamecmp(x, y)
char **x, **y;
{
#define codemap(a) (isdrvmk(a) ? -257 : isdelim(a) ? -256 : a)
register unsigned char *p, *q;
int a, b;
for(p = (unsigned char *)*x, q = (unsigned char *)*y; ; p++, q++){
if(iskanjipos(p) || iskanjipos(q)){
if(*p != *q) return *p - *q;
if(p[1] != q[1]) return p[1] - q[1];
p++, q++;
continue;
}
a = *p, b = *q;
if(!a && !b) return 0;
a = codemap(a), b = codemap(b);
if(a != b) return a - b;
}
}
static void addarg(s)
register char *s;
{
register int saveac = newac;
if(*s == RESPF){
addindarg(++s);
if(saveac == newac){
fprintf(stderr,
"No files found in response file %s\n",
strcmp(s, "-") ? s : "<stdin>");
/* not exit */
}
} else {
addfarg(s);
if(saveac != newac){
qsort((char *)&newav[saveac], newac - saveac,
sizeof(char *), fnamecmp);
} else {
/*
fprintf(stderr, "%s: File not found.\n", unixname(s));
exit(1);
*/
#ifndef UNIX
add1arg(s);
/* In case of using it as a plain string... */
#endif
}
}
}
static void addfarg(s)
register char *s;
#ifdef UNIX
{
register FILE *dirfind;
int saveac = newac;
if(isdir(s)){
if(NULL == (dirfind = dirfindopen(s))) (perror(s), exit(1));
addindfarg(dirfind);
fclose(dirfind);
wait(NULL);
if(saveac == newac){
fprintf(stderr,
"No files found in directory %s\n", s);
/* not exit */
}
} else {
add1arg(s);
}
}
#else
{
struct find_t mydta;
register char *tmppath;
#ifdef DEBUG
fprintf(stderr, "looking for '%s'...\n", s);
#endif
if(isdotdir(s) || isdirarg(s)){
adddirarg(s);
} else if(0 == _dos_findfirst(dosname(s), 0x16, &mydta)){
do {
#ifdef DEBUG
fprintf(stderr, "found '%s' in '%s'...\n",
mydta . name, s);
#endif
if(*mydta . name == '.') continue; /* '.', '..' */
tmppath = strdircatsave(s, mydta . name);
if(mydta . attrib & 0x10){
adddirarg(tmppath);
} else {
add1arg(unixname(tmppath));
}
free(tmppath);
} while(0 == _dos_findnext(&mydta));
}
}
#endif /* UNIX */
static void adddirarg(s)
register char *s;
{
addfarg(s = strpathcatsave(s, "*.*"));
free(s);
}
static void addindfarg(resf)
register FILE *resf;
{
#define MAXLEN 256
#define MAXFMT "%256s"
char name[MAXLEN + 1];
register int c;
while(1 == fscanf(resf, MAXFMT, name)){
if(c = getc(resf), !is_space(c)){
fprintf(stderr, "Too long name: %s%c...\n", name, c);
exit(1);
}
addarg(name);
if(c == EOF) break; /* else ungetc(c, resf); */
}
}
static void addindarg(s)
register char *s;
{
register FILE *resf;
if(!strcmp(s, "-")){
addindfarg(stdin);
} else {
if(NULL == (resf = fopen(s, "r"))){
perror(unixname(s)), exit(1);
}
addindfarg(resf);
fclose(resf);
}
}
static void add1arg(s)
register char *s;
{
while(newac >= newavsize){
newavsize += 20;
newav = (char **)emalloc((char *)newav,
(newavsize + 1) * sizeof(char *));
}
#ifdef DEBUG
fprintf(stderr, "allocated %d, saved into %d\n", newavsize, newac);
#endif
newav[newac++] = strsave(s);
}
#ifdef DEBUG
main(ac, av)
char **av;
{
int i;
setargs(&ac, &av, 0);
for(i = 0; i < ac; i++) printf("arg %d = %s\n", i, av[i]);
return 0;
}
#endif