home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
001-099
/
ff055.lzh
/
Csh
/
comm1.c
next >
Wrap
C/C++ Source or Header
|
1987-03-01
|
24KB
|
1,006 lines
/*
* COMM1.C
*
* Matthew Dillon, August 1986
*
* version 2.05M (Manx Version and Additions) by Steve Drew 20-Jan-87
*
*/
#include "shell.h"
typedef struct FileInfoBlock FIB;
#define DIR_SHORT 0x01
#define DIR_FILES 0x02
#define DIR_DIRS 0x04
#define DIR_EXCLUDE 0x08
#define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var)))
#define C_TO_BPTR(strtag, var) ((struct strtag *)(((ULONG)var)>>2))
extern char *btocstr();
extern int has_wild;
char cwd[256];
struct FileLock *Clock;
do_sleep()
{
register int i;
if (ac == 2) {
i = atoi(av[1]);
while (i > 0) {
Delay ((long)50*2);
i -= 2;
if (CHECKBREAK())
break;
}
}
return (0);
}
do_number()
{
return (0);
}
do_cat()
{
FILE *fopen(), *fi;
int i;
char buf[256];
if (ac == 1) {
while (gets(buf)) {
if (CHECKBREAK()) break;
puts(buf);
}
clearerr(stdin);
return (0);
}
for (i = 1; i < ac; ++i) {
if ((fi = fopen (av[i], "r")) != 0) {
while (fgets(buf,256,fi)) {
fputs(buf,stdout);
fflush(stdout);
if (CHECKBREAK()) {
breakreset();
break;
}
}
fclose (fi);
} else {
fprintf (stderr, "could not open %s\n", av[i]);
}
}
return (0);
}
/* things shared with disp_entry */
int filecount, col;
long bytes, blocks;
do_dir(garbage, com)
char *garbage;
{
void disp_entry();
struct DPTR *dp;
struct InfoData *info;
char *name;
int i = 0, stat, clen, more;
char options = 0;
char *c;
char exclude[40];
char lspec[256];
char volume[40];
char *volname();
char *dates();
col = filecount = 0;
bytes = blocks = 0L;
while((++i < ac) && (av[i][0] == '-')) {
for (c = av[i]+1; *c ; c++) {
switch(*c) {
case 's':
options |= DIR_SHORT;
break;
case 'f':
options |= DIR_FILES;
break;
case 'd':
options |= DIR_DIRS;
break;
case 'e':
options |= DIR_EXCLUDE;
strcpy(exclude,"*");
strcat(exclude,av[++i]);
strcat(exclude,"*");
break;
default:
break;
}
}
}
if (ac == i) {
++ac;
av[i] = "";
if (has_wild)
return(0);
}
if (!(options & (DIR_FILES | DIR_DIRS))) options |= (DIR_FILES | DIR_DIRS);
for (; i < ac; ++i) {
if (!(dp = dopen (av[i], &stat)))
continue;
if (com < 0) {
info = (struct InfoData *)AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC);
if (Info (dp->lock, info)) {
printf ("Unit:%2ld Errs:%3ld Used: %-4ld %3ld%% Free: %-4ld Volume: %s\n",
info->id_UnitNumber,
info->id_NumSoftErrors,
info->id_NumBlocksUsed,
(info->id_NumBlocksUsed * 100)/ info->id_NumBlocks,
(info->id_NumBlocks - info->id_NumBlocksUsed),
volname(dp->lock,volume));
} else {
pError (av[i]);
}
FreeMem (info,(long) sizeof(*info));
dclose(dp);
continue;
return(0);
}
/* start of directory routine */
c = av[i];
clen = strlen(c);
if (!stat || has_wild) { /* if not wild and is a dir don't */
/* extract dir from file name */
while (clen && c[clen] != '/' && c[clen] != ':') clen--;
if (c[clen] == ':' || c[clen] == '/') clen++;
c[clen] = '\0';
}
if (!clen) c = cwd;
if (strcmp (c, &lspec) != 0) {
strcpy(lspec, c);
if (col) printf("\n");
printf ("Directory of %s\n", lspec);
fflush(stdout);
col = 0;
}
more = stat;
do {
if (more && !has_wild) {
*lspec = '\0';
if (!(more = dnext(dp, &name, &stat)))
break;
}
if (CHECKBREAK()) {
i = ac;
break;
}
disp_entry (dp->fib, options,exclude);
} while(more && !has_wild);
dclose(dp);
} /* end for */
if (col) printf("\n");
if (filecount > 1) {
blocks += filecount; /* account for dir blocks */
printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount);
}
return (0);
}
char *
volname(lock,buf)
struct FileLock *lock;
char *buf;
{
struct DeviceList *dl;
char *p;
Forbid();
/* Only way I know to get Volume label since InfoData */
/* seems to always have NULL for this string */
lock = BPTR_TO_C(FileLock, lock);
dl = BPTR_TO_C(DeviceList, lock->fl_Volume);
p = btocstr(dl->dl_Name,buf);
Permit();
return p;
}
void
disp_entry(fib, options, exclude)
char options;
char *exclude;
register struct FileInfoBlock *fib;
{
char str[5];
int italics;
char s;
if (!(((options & DIR_FILES) && (fib->fib_DirEntryType < 0)) ||
((options & DIR_DIRS) && (fib->fib_DirEntryType > 0))))
return;
if ((options & DIR_EXCLUDE) && (compare_ok(exclude,fib->fib_FileName)))
return;
if (!(options & DIR_SHORT)) {
str[4] = '\0';
str[0] = (fib->fib_Protection & FIBF_READ) ? '-' : 'r';
str[1] = (fib->fib_Protection & FIBF_WRITE) ? '-' : 'w';
str[2] = (fib->fib_Protection & FIBF_EXECUTE) ? '-' : 'e';
str[3] = (fib->fib_Protection & FIBF_DELETE) ? '-' : 'd';
printf (" %-24s %s ", fib->fib_FileName, str);
if (fib->fib_DirEntryType < 0) printf("%6ld %4ld", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
else printf(" Dir ");
printf(" %s", dates(&fib->fib_Date));
fflush(stdout);
}
else {
if ((col == 3) && strlen(fib->fib_FileName)>18) {
printf("\n");
col = 0;
}
if (fib->fib_DirEntryType > 0) {
printf ("\033[3m");
italics = 1;
}
if (strlen(fib->fib_FileName)>18) {
printf(" %-37s",fib->fib_FileName);
col += 2;
}
else {
printf(" %-18s",fib->fib_FileName);
col++;
}
if (col > 3) {
printf("\n");
col = 0;
}
if (italics) printf("\033[0m");
}
fflush(stdout);
blocks += fib->fib_NumBlocks;
bytes += fib->fib_Size;
filecount++;
return;
}
/* converts dos date stamp to a time string of form dd-mmm-yy */
char *
dates(dss)
struct DateStamp *dss;
{
register struct tm tm;
register long time, t;
register int i;
static char timestr[20];
static char months[12][4] = {
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"
};
static char days[12] = {
31,28,31,30,31,30,31,31,30,31,30,31
};
time = dss->ds_Days * 24 * 60 * 60 + dss->ds_Minute * 60 +
dss->ds_Tick/TICKS_PER_SECOND;
tm.tm_sec = time % 60; time /= 60;
tm.tm_min = time % 60; time /= 60;
tm.tm_hour= time % 24; time /= 24;
tm.tm_wday= time % 7;
tm.tm_year= 78 + (time/(4*365+1)) * 4; time %= 4 * 365 + 1;
while (time) {
t = 365;
if ((tm.tm_year&3) == 0) t++;
if (time < t) break;
time -= t;
tm.tm_year++;
}
tm.tm_yday = ++time;
for (i=0;i<12;i++) {
t = days[i];
if (i == 1 && (tm.tm_year&3) == 0) t++;
if (time <= t) break;
time -= t;
}
tm.tm_mon = i;
tm.tm_mday = time;
sprintf(timestr,"%02d-%s-%2d %02d:%02d:%02d\n",tm.tm_mday,
months[tm.tm_mon],tm.tm_year,
tm.tm_hour,tm.tm_min,tm.tm_sec);
return(timestr);
}
date()
{
struct DateStamp dss;
char *s, *dates();
DateStamp(&dss);
s = dates(&dss);
printf("%s",s);
return(0);
}
do_quit()
{
if (Src_stack) {
Quit = 1;
return(do_return());
}
main_exit (0);
}
do_echo(str)
char *str;
{
register char *ptr;
char nl = 1;
for (ptr = str; *ptr && *ptr != ' '; ++ptr);
if (*ptr == ' ')
++ptr;
if (av[1] && strcmp (av[1], "-n") == 0) {
nl = 0;
ptr += 2;
if (*ptr == ' ')
++ptr;
}
printf("%s",ptr);
fflush(stdout);
if (nl)
printf("\n");
return (0);
}
do_source(str)
char *str;
{
register FILE *fi;
char buf[256];
if (Src_stack == MAXSRC) {
printf (stderr,"Too many source levels\n");
return(-1);
}
if ((fi = fopen (av[1], "r")) == 0) {
fprintf (stderr,"Cannot open %s\n", av[1]);
return(-1);
}
set_var(LEVEL_SET, V_PASSED, next_word(next_word(str)));
++H_stack;
Src_pos[Src_stack] = 0;
Src_base[Src_stack] = (long)fi;
++Src_stack;
while (fgets (buf, 256, fi)) {
buf[strlen(buf)-1] = '\0';
Src_pos[Src_stack - 1] += 1+strlen(buf);
if (Verbose)
fprintf(stderr,"%s\n",buf);
exec_command (buf);
if (CHECKBREAK())
break;
}
--H_stack;
--Src_stack;
unset_level(LEVEL_LABEL + Src_stack);
unset_var(LEVEL_SET, V_PASSED);
fclose (fi);
return (0);
}
/*
* CD
*
* CD(str, -1) -do pwd and display current cd. if str = NULL don't disp.
* CD(str, 0) -do CD operation.
*
* standard operation: breakup path by '/'s and process independantly
* x: -reset cwd base
* .. -remove last cwd element
* N -add N or /N to cwd
*/
do_cd(str, com)
char *str;
{
char sc, *ptr;
char *name;
if (com < 0) {
struct FileLock *lock, *newlock;
FIB *fib;
int i, len;
fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
if ((Clock = (struct FileLock *)Myprocess->pr_CurrentDir) == 0)
attempt_cd(":"); /* if we just booted 0 = root lock */
lock = (struct FileLock *)DupLock(Clock);
cwd[i = 255] = '\0';
while (lock) {
newlock = (struct FileLock *)ParentDir(lock);
Examine(lock, fib);
name = fib->fib_FileName;
if (*name == '\0') /* HACK TO FIX RAM: DISK BUG */
name = "ram";
len = strlen(name);
if (newlock) {
if (i == 255) {
i -= len;
bmov(name, cwd + i, len);
} else {
i -= len + 1;
bmov(name, cwd + i, len);
cwd[i+len] = '/';
}
} else {
i -= len + 1;
bmov(name, cwd + i, len);
cwd[i+len] = ':';
}
UnLock(lock);
lock = newlock;
}
FreeMem(fib, (long)sizeof(FIB));
bmov(cwd + i, cwd, 256 - i);
if (str)
puts(cwd);
set_var(LEVEL_SET, V_CWD, cwd);
/* put the current dir name in our CLI task structure */
ptr = (char *)((ULONG)((struct CommandLineInterface *)
BADDR(Myprocess->pr_CLI))->cli_SetName << 2);
ptr[0] = strlen(cwd);
movmem(cwd,ptr+1,(int)ptr[0]);
return (0);
}
str = next_word(str);
if (*str == '\0')
puts(cwd);
str[strlen(str)+1] = '\0'; /* add second \0 on end */
while (*str) {
for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
switch (*ptr) {
case ':':
sc = ptr[1];
ptr[1] = '\0';
if (attempt_cd(str))
strcpy(cwd, str);
ptr[1] = sc;
break;
case '\0':
case '/':
*ptr = '\0';
if (strcmp(str, "..") == 0 || str == ptr)
str = "/";
if (*str && attempt_cd(str)) {
if (*str == '/') {
rmlast(cwd);
} else {
if (cwd[0] == 0 || cwd[strlen(cwd)-1] != ':')
strcat(cwd, "/");
strcat(cwd, str);
}
}
break;
}
str = ptr + 1;
}
do_cd(NULL,-1);
}
attempt_cd(str)
char *str;
{
struct FileLock *oldlock, *filelock;
if (filelock = (struct FileLock *)Lock(str, ACCESS_READ)) {
if (isdir(str)) {
if (oldlock = (struct FileLock *)CurrentDir(filelock))
UnLock(oldlock);
Clock = filelock;
return (1);
}
UnLock(filelock);
ierror(str, 212);
} else {
ierror(str, 205);
}
return (0);
}
/*
* remove last component. Start at end and work backwards until reach
* a '/'
*/
rmlast(str)
char *str;
{
char *ptr = str + strlen(str) - 1;
while (ptr != str && *ptr != '/' && *ptr != ':')
--ptr;
if (*ptr != ':')
ptr[0] = '\0';
else
ptr[1] = '\0';
}
do_mkdir()
{
register int i;
register struct FileLock *lock;
for (i = 1; i < ac; ++i) {
if (lock = (struct FileLock *)CreateDir (av[i])) {
UnLock (lock);
continue;
}
pError (av[i]);
}
return (0);
}
do_mv()
{
char dest[256];
register int i;
char *str;
--ac;
if (isdir(av[ac])) {
for (i = 1; i < ac; ++i) {
str = av[i] + strlen(av[i]) - 1;
while (str != av[i] && *str != '/' && *str != ':')
--str;
if (str != av[i])
++str;
if (*str == 0) {
ierror(av[i], 508);
return (-1);
}
strcpy(dest, av[ac]);
if (dest[strlen(dest)-1] != ':')
strcat(dest, "/");
strcat(dest, str);
if (Rename(av[i], dest) == 0)
break;
}
if (i == ac)
return (1);
} else {
i = 1;
if (ac != 2) {
ierror("", 507);
return (-1);
}
if (Rename (av[1], av[2]))
return (0);
}
pError (av[i]);
return (-1);
}
rm_file(file)
char *file;
{
if (has_wild) printf(" %s...",file);
fflush(stdout);
if (!DeleteFile(file))
pError (file);
else
if (has_wild) printf("Deleted\n");
}
do_rm()
{
register short i, recur;
recur = (strncmp(av[1], "-r", 2)) ? 0 : 1;
for (i = 1 + recur; i < ac; ++i) {
if (CHECKBREAK()) break;
if (isdir(av[i]) && recur)
rmdir(av[i]);
if (!(recur && av[i][strlen(av[i])-1] == ':'))
rm_file(av[i]);
}
return (0);
}
rmdir(name)
char *name;
{
register struct FileLock *lock, *cwd;
register FIB *fib;
register char *buf;
buf = (char *)AllocMem(256L, MEMF_PUBLIC);
fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
if (lock = (struct FileLock *)Lock(name, ACCESS_READ)) {
cwd = (struct FileLock *) CurrentDir(lock);
if (Examine(lock, fib)) {
buf[0] = 0;
while (ExNext(lock, fib)) {
if (CHECKBREAK()) break;
if (isdir(fib->fib_FileName))
rmdir(fib->fib_FileName);
if (buf[0]) {
rm_file(buf);
}
strcpy(buf, fib->fib_FileName);
}
if (buf[0] && !CHECKBREAK()) {
rm_file(buf);
}
}
UnLock(CurrentDir(cwd));
} else {
pError(name);
}
FreeMem(fib, (long)sizeof(FIB));
FreeMem(buf, 256L);
}
do_history()
{
register struct HIST *hist;
register int i = H_tail_base;
register int len = (av[1]) ? strlen(av[1]) : 0;
for (hist = H_tail; hist; hist = hist->prev) {
if (len == 0 || strncmp(av[1], hist->line, len) == 0) {
printf ("%3d ", i);
puts (hist->line);
}
++i;
if (CHECKBREAK())
break;
}
return (0);
}
do_mem()
{
long cfree, ffree;
extern long AvailMem();
Forbid();
cfree = AvailMem (MEMF_CHIP);
ffree = AvailMem (MEMF_FAST);
Permit();
if (ffree) {
printf ("FAST memory: %ld\n", ffree);
printf ("CHIP memory: %ld\n", cfree);
}
printf ("Total Free: %ld\n", cfree + ffree);
return(0);
}
/*
* foreach var_name ( str str str str... str ) commands
* spacing is important (unfortunetly)
*
* ac=0 1 2 3 4 5 6 7
* foreach i ( a b c ) echo $i
* foreach i ( *.c ) "echo -n "file ->";echo $i"
*/
do_foreach()
{
register int i, cstart, cend, old;
register char *cstr, *vname, *ptr, *scr, *args;
cstart = i = (*av[2] == '(') ? 3 : 2;
while (i < ac) {
if (*av[i] == ')')
break;
++i;
}
if (i == ac) {
fprintf (stderr,"')' expected\n");
return (-1);
}
++H_stack;
cend = i;
vname = strcpy(malloc(strlen(av[1])+1), av[1]);
cstr = compile_av (av, cend + 1, ac);
ptr = args = compile_av (av, cstart, cend);
while (*ptr) {
while (*ptr == ' ' || *ptr == 9)
++ptr;
scr = ptr;
if (*scr == '\0')
break;
while (*ptr && *ptr != ' ' && *ptr != 9)
++ptr;
old = *ptr;
*ptr = '\0';
set_var (LEVEL_SET, vname, scr);
if (CHECKBREAK())
break;
exec_command (cstr);
*ptr = old;
}
--H_stack;
free (args);
free (cstr);
unset_var (LEVEL_SET, vname);
free (vname);
return (0);
}
do_forever(str)
char *str;
{
int rcode = 0;
char *ptr = next_word(str);
++H_stack;
for (;;) {
if (CHECKBREAK()) {
rcode = 20;
break;
}
if (exec_command (ptr) < 0) {
str = get_var(LEVEL_SET, V_LASTERR);
rcode = (str) ? atoi(str) : 20;
break;
}
}
--H_stack;
return (rcode);
}
/*
* CP file file
* CP file file file... destdir
* CP [-r] dir dir dir... destdir
*/
char *errstr; /* let's be alittle more informative */
do_copy()
{
register short recur, i, ierr;
register char *destname;
register char destisdir;
register FIB *fib;
errstr = "";
ierr = 0;
fib = (FIB *)AllocMem((long)sizeof(FIB), 0);
recur = (strncmp(av[1], "-r", 2)) ? 0 : 1;
destname = av[ac - 1];
if (ac < recur + 3) {
ierr = 500;
goto done;
}
destisdir = isdir(destname);
if (ac > recur + 3 && !destisdir) {
ierr = 507;
goto done;
}
/*
* copy set: reduce to:
* file to file file to file
* dir to file (NOT ALLOWED)
* file to dir dir to dir
* dir to dir dir to dir
*
*/
fflush(stdout);
stdout->_buflen = 1;
for (i = recur + 1; i < ac - 1; ++i) {
short srcisdir = isdir(av[i]);
if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
continue; /* getting copied if specified */
/* from wild expansion */
if (CHECKBREAK())
break;
if (srcisdir) {
struct FileLock *srcdir, *destdir;
if (!destisdir) { /* disallow dir to file */
ierr = 507;
goto done;
}
if (!(destdir = (struct FileLock *)Lock(destname, ACCESS_READ))) {
ierr = 205;
errstr = destname;
goto done;
}
if (!(srcdir = (struct FileLock *)Lock(av[i], ACCESS_READ))) {
ierr = 205;
errstr = av[i];
UnLock(destdir);
goto done;
}
ierr = copydir(srcdir, destdir, recur);
UnLock(srcdir);
UnLock(destdir);
if (ierr)
break;
} else { /* FILE to DIR, FILE to FILE */
struct FileLock *destdir, *srcdir, *tmp;
char *destfilename;
srcdir = (struct FileLock *)((struct Process *)FindTask(0))->pr_CurrentDir;
if (destisdir) {
if ((tmp = (struct FileLock *)Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)){
if (tmp) UnLock(tmp);
ierr = 205;
errstr = av[i];
goto done;
}
UnLock(tmp);
destdir = (struct FileLock *)Lock(destname, ACCESS_READ);
destfilename = fib->fib_FileName;
} else {
destdir = srcdir;
destfilename = destname;
}
printf(" %s..",av[i]);
ierr = copyfile(av[i], srcdir, destfilename, destdir);
if (destisdir)
UnLock(destdir);
if (ierr)
break;
}
}
done:
stdout->_buflen = STDBUF; /* set back to buffr'd */
FreeMem(fib, (long)sizeof(*fib));
if (ierr) {
ierror(errstr, ierr);
return(20);
}
return(0);
}
copydir(srcdir, destdir, recur)
register struct FileLock *srcdir, *destdir;
{
struct FileLock *cwd;
register FIB *srcfib;
register struct FileLock *destlock, *srclock;
int ierr;
static int level;
level++;
ierr = 0;
srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
if (Examine(srcdir, srcfib)) {
while (ExNext(srcdir, srcfib)) {
if (CHECKBREAK())
break;
if (srcfib->fib_DirEntryType < 0) {
printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
if (ierr)
break;
} else {
if (recur) {
cwd = (struct FileLock *)CurrentDir(srcdir);
if (srclock = (struct FileLock *)Lock(srcfib->fib_FileName, ACCESS_READ)) {
CurrentDir(destdir);
if (!(destlock = (struct FileLock *)
Lock(srcfib->fib_FileName))) {
destlock = (struct FileLock *)CreateDir(srcfib->fib_FileName);
printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
" ",srcfib->fib_FileName);
}
else
printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
if (destlock) {
ierr = copydir(srclock, destlock, recur);
UnLock(destlock);
} else {
ierr = (int)((long)IoErr());
}
UnLock(srclock);
} else {
ierr = (int)((long)IoErr());
}
CurrentDir(cwd);
if (ierr)
break;
}
}
}
} else {
ierr = (int)((long)IoErr());
}
--level;
FreeMem(srcfib, (long)sizeof(FIB));
return(ierr);
}
copyfile(srcname, srcdir, destname, destdir)
char *srcname, *destname;
struct FileLock *srcdir, *destdir;
{
struct FileLock *cwd;
struct FileHandle *f1, *f2;
long i;
int ierr;
char *buf;
buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR);
if (buf == NULL) {
ierr = 103;
goto fail;
}
ierr = 0;
cwd = (struct FileLock *)CurrentDir(srcdir);
f1 = Open(srcname, MODE_OLDFILE);
if (f1 == NULL) {
errstr = srcname;
ierr = 205;
goto fail;
}
CurrentDir(destdir);
f2 = Open(destname, MODE_NEWFILE);
if (f2 == NULL) {
Close(f1);
ierr = (int)((long)IoErr());
errstr = destname;
goto fail;
}
while (i = Read(f1, buf, 8192L))
if (Write(f2, buf, i) != i) {
ierr = (int)((long)IoErr());
break;
}
Close(f2);
Close(f1);
if (!ierr) {
printf("..copied\n");
}
else {
DeleteFile(destname);
printf("..Not copied..");
}
fail:
if (buf)
FreeMem(buf, 8192L);
CurrentDir(cwd);
return(ierr);
}