More Unix Style Tools for IBMPC.
Mohsen Banan
mohsen at tikal.UUCP
Thu Aug 29 02:11:08 AEST 1985
Here are some unix style tools that also run on IBM PC.
Cut it and pass it through sh.
Read readme.ut1 first.
Here is a list of the programs in this posting:
expand, dost2b, dosb2t, hxd, which, crc16, sarch.
----------------------- CUT HERE ----------------------
# The rest of this file is a shell script which will extract:
# readme.ut1 mkp makefile pcust1.bat mbstd.h msc3.h crc16.c dosb2t.c dost2b.c expand.c fcrc16.c hxd.c sarch.c which.c
echo x - readme.ut1
cat >readme.ut1 <<'!Funky!Stuff!'
Here are a few simple tools that run identically or very similarly
under msdos and unix.
I am calling them ust1, Unix Style Tools. Couldn't come up with
a better name.
They have only minimally been tested under msdos and bsd4.2.
MSC 3.0 was used under msdos.
I did make an effort to make the code portable. They probably would
run under a few other systems.
Mail bug reports and problems to me. I'll re-post.
expand:
* Expand mimics Unix's expand. It is not a full implementation.
* Does not support [-tab1,tab2,..,tabn].
* Expand is a filter.
* It processes the named files or the standard input.
* It writes to standard output with tabs changed into blanks.
*
* Usages:
* expand [-tabstop] [i_files]
Back space can easily be added to it.
dost2b:
* dost2b is a filter.
* dost2b processes i_files or the standard input.
* dost2b writes to o_file or standard output.
* Converts a DOS text file to binary file.
* Replaces <cr><lf> to <lf>.
*
* Usages:
* dost2b [-o] <o_file> <i_files>
dosb2t:
* dosb2t is a filter.
* dosb2t processes i_files or the standard input.
* dosb2t writes to o_file or standard output.
* Converts a DOS binary file to text file.
* Replaces <lf> with <cr><lf>.
*
* Usages:
* dosb2t [-o] <o_file> <i_files>
hxd:
* hxd, Hexadecimal dump is similar unix's "od -x"
* Displays the contents of a file in hexadecimal.
* If a byte is printable, it is also printed.
* For each in put file name of the file is first emited.
* file: <i_file>
* last line for each input file is length of the file in
* "dec_add:hex_add" format.
*
* Usages:
* hxd [-o] <o_file> <i_files>
See Comments in hxd.c.
which:
* Tries to mimic Unix's which as closely as possible.
*
* Usages:
* which <i_files>
This is basically Larry Barello's which.
For DOS .{com,exe,bat} are tested for existance.
Only the first one that exists is printed.
Internal DOS programs could later be added.
crc16:
This is basically Hugh Redelmeir's version.
I needed to modify it so that it could also be
used by sarch.
sarch:
* This is a simple archive utility program.
* Sarch tries to only rely on the C stdio library functions.
* When transferring multiple files between two machines that only have a
* single file transfer utility, sarch becomes handy. Multiple files
* are converted to a sinle file on one end, transfered to the other
* machine and extracted to the original files at the destination.
* System dependent features are very few, keeping it simple
* and portable. Efficiency is sacrificed for portability.
* CRCs are computed when updateing and when extracting.
*
* Usage:
* sarch -{m,u,x,a,t} archname file1 .. filen
* -m Print file names within the archive.
* -u Add or update files to the archive.
* -x Extract files from archive.
* -a Extract all files from the rachive.
* -t PCDOS related. When extracting, test mode is set.
Sarch is NOT COMPLETE.
I am posting it because it can be useful if used carefully.
No flames on this one, please.
I am also not happy with th command syntax.
Only -u and -a work. As is, it is only useful for moving files
around.
sarch -u ar file1 filen , on one end.
sarch -a ar , on the other end.
FILES:
mkp:
Is a Csh script that runs make.
It can be useful when you are supporting native and cross
development. Some don't like it. I do.
makefile:
File dependencies only. Needs mkp.
pcust1.bat:
run this on the pc to create everything.
mbstd.h:
Standard Header I use.
expand.c dost2b.c dosb2t.c hxd.c sarch.c which.c fcrc16.c crc16.c:
C source files.
readme.ut1:
This file.
TO RUN:
bsd4.2
first make mkp executable.
mkp
msdos, msc
make sure that all headers and libraries are there.
make sure ssetargv.obj is in current directory.
run pcust1.bat
!Funky!Stuff!
echo x - mkp
cat >mkp <<'!Funky!Stuff!'
#!/bin/csh -f
# This is the make pre-processor program written in the 'C' shell.
#
# mkp defines a group of parameters and passes them to make.
# SWITCHES:
# -f <filename>
# source <filename. priore to invoking make.
# If -f is not present and .mkprc exists in the current directory
# it is sourced. Otherwise if .mkprc exists in the home directory
# it is sourced.
# --
# argument parsing is terminated remainder of command line is passed
# to make as is.
#
set MKPFILE=.mkprc
set mkpname=$0
set mkpname=$mkpname:t
# ### VISIBLE MAKE TOOLS
set MAKE=make
set CC=cc
set AS="as -"
set LK=""
set LD=""
set LINT="lint -u"
set REMOVE="rm -f"
set CTAGS="ctags -w"
# Internal parametrs
set INCFLAGS = -I.
# ### VISIBLE MAKE PARAMETERS
#set CFLAGS = "${INCFLAGS} -DBSD4_2 -Uunix -DMSDOS"
set CFLAGS = "${INCFLAGS} -DBSD4_2 "
set LINTFLAGS = ${INCFLAGS}
set TARGETS
# MKP FLAGS
set S_MKPFILE
#
umask 002
#
#
# Gather command line options
#
foreach i ($*)
switch ($1)
case -f:
shift argv
set S_MKPFILE=$1
breaksw
case --:
shift argv
break
default:
break
breaksw
endsw
shift argv
end
#
#
#
#
if ("$S_MKPFILE" != "") then
set MKPFILE = "$S_MKPFILE"
source $MKPFILE
else if (-f $MKPFILE) then
source $MKPFILE
else if (-f $HOME/$MKPFILE) then
source $HOME/$MKPFILE
endif
#
set TARGETS="$*"
#
$MAKE "CC=$CC" "AS=$AS" \
"CFLAGS=$CFLAGS" "LINTFLAGS=$LINTFLAGS" \
"LINT=$LINT" \
"REMOVE=$REMOVE" "CTAGS=$CTAGS" \
$TARGETS
set ret=$status
if ("$ret" != "0") then
exit 1
endif
exit 0
!Funky!Stuff!
echo x - makefile
cat >makefile <<'!Funky!Stuff!'
# ::::::::::::::::::::::::::::::::::::::::::::::::::
#
# File: Makefile
# Description: Makefile for creating UST1
#
#
# Audit Trail: $Log: makefile,v $
# Revision 1.1 85/08/28 08:38:38 mohsen
# original posting to the net
#
#
# $Header: makefile,v 1.1 85/08/28 08:38:38 mohsen Exp $
#
# ::::::::::::::::::::::::::::::::::::::::::::::::::
MAKEFILE = makefile
TARGET = ust1
PUB_H = mbstd.h msc3.h
LCL_H =
LCL_C = expand.c dost2b.c dosb2t.c hxd.c sarch.c which.c fcrc16.c \
crc16.c
C_SRC = ${PUB_H} ${LCL_H} ${LCL_C}
${TARGET}: expand dost2b dosb2t hxd crc16 which sarch
#
expand: expand.o
cc -o expand expand.o
#
dost2b: dost2b.o
cc -o dost2b dost2b.o
#
dosb2t: dosb2t.o
cc -o dosb2t dosb2t.o
#
hxd: hxd.o
cc -o hxd hxd.o
#
crc16: crc16.o fcrc16.o
cc -o crc16 crc16.o fcrc16.o
#
sarch: sarch.o
cc -o sarch sarch.o fcrc16.o
#
which: which.o
cc -o which which.o
#
e_make:
@echo ${MAKEFILE}
e_pub_h:
@echo ${PUB_H}
e_lcl_h:
@echo ${LCL_H}
e_lcl_c:
@echo ${LCL_C}
e_c_src:
@echo ${C_SRC}
#
ctags: ${LCL_C}
$(CTAGS) $(LCL_C)
#
lint:
$(LINT) $(LCL_C)
!Funky!Stuff!
echo x - pcust1.bat
cat >pcust1.bat <<'!Funky!Stuff!'
cl -c -DMSDOS expand.c
cl -o expand expand.obj ssetargv.obj
cl -c -DMSDOS dost2b.c
cl -o dost2b dost2b.obj ssetargv.obj
cl -c -DMSDOS dosb2t.c
cl -o dosb2t dosb2t.obj ssetargv.obj
cl -c -DMSDOS hxd.c
cl -o hxd hxd.obj ssetargv.obj
cl -c -DMSDOS fcrc16.c
cl -c -DMSDOS crc16.c
cl -o crc16 crc16.obj fcrc16.obj ssetargv.obj
cl -c -DMSDOS sarch.c
cl -o sarch sarch.obj fcrc16.obj ssetargv.obj
cl -c -DMSDOS which.c
cl -o which which.obj ssetargv.obj
!Funky!Stuff!
echo x - mbstd.h
cat >mbstd.h <<'!Funky!Stuff!'
#ifndef MBSTD_H
#define MBSTD_H
#define CHAR char
#define SCHAR char
typedef unsigned char UCHAR;
#define INT int
#define SINT int
typedef unsigned int UINT;
#define SHORT short
#define SSHORT short
typedef unsigned short USHORT;
#define LONG long
#define SLONG long
typedef unsigned long ULONG;
#define DOUBLE double
#define BOOL int
#define SUCC_FAIL int
#ifndef VOID
#define VOID void
#endif
#define STATIC static /* Names not needed outside this src module */
#define LOCAL /* Names not needed outside this software module */
#define LCL_XTRN extern /* Names defined within this software module */
#define PUBLIC /* Names needed outside this software module */
#define EXTERN extern /* Names defined outside this software module */
#define TRUE 1
#define FALSE 0
#define SUCCESS 0
#define FAIL (-1)
#endif MBSTD_H
!Funky!Stuff!
echo x - msc3.h
cat >msc3.h <<'!Funky!Stuff!'
#ifndef MSC3_H
#define MSC3_H
#ifdef unix
#define O_TEXT 0x4000
#define O_BINARY 0x8000
setmode(handle, mode)
int handle;
int mode;
{}
#endif
#endif MSC3_H
!Funky!Stuff!
echo x - crc16.c
cat >crc16.c <<'!Funky!Stuff!'
/*+
* File: crc16.c
* Description:
* Computes crc for the named filenames.
* Output has this formatt.
* file=[i_file], size=[fsize], crc=[decval](dec)=[hexval](hex)
*
* Usages:
* crc16 <i_files>
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
* Functions:
*
*
* Audit Trail: $Log: crc16.c,v $
* Revision 1.1 85/08/28 08:38:12 mohsen
* original posting to the net
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: crc16.c,v 1.1 85/08/28 08:38:12 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef unix
#include "msc3.h"
#endif
/* #defines */
/* external variables */
/* referenced external function declarations */
EXTERN USHORT fcrc16();
/* internal function declarations */
PUBLIC VOID crc16();
PUBLIC VOID cant_open();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
crc16(argc, argv);
}
/*<
* Function:crc16
* Description:
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
crc16 (argc,argv)
INT argc;
CHAR * argv[];
{
FILE * i_fp;
FILE * o_fp;
INT i;
USHORT crc;
LONG fsize ;
i_fp = stdin;
o_fp = stdout;
prog_name = argv[0];
for (i=1; i<argc; ++i) {
if (*argv[i] == '-') {
/* To handle concatenated switches */
INT j;
j=i;
while (*(++argv[j])) {
switch (*argv[j]) {
case 'o':
case 'O':
if ( !(o_fp = fopen(argv[++i], "w")) ) {
cant_open (prog_name, argv[i]);
exit (1);
}
break;
default:
usage();
exit(1);
} /* switch (*argv[j]) */
} /* while (*(++argv[j])) */
} /* if '-' */
else {
if (!(i_fp = fopen (argv[i], "r"))) {
cant_open (prog_name, argv[i]);
exit (1);
}
setmode (fileno(i_fp), O_BINARY);
setmode (fileno(o_fp), O_TEXT);
crc = fcrc16 (i_fp, 0, &fsize);
fprintf (o_fp, "file=%s, size=%ld, crc=%u(dec)=%x(hex)\n",
argv[i], fsize, crc, crc);
fclose (i_fp);
}
} /* for i<argc */
fclose (o_fp);
exit (0);
}
PUBLIC VOID
cant_open (prog_name,filename)
CHAR * prog_name;
CHAR * filename;
{
fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
}
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s <i_files> \n", prog_name);
}
!Funky!Stuff!
echo x - dosb2t.c
cat >dosb2t.c <<'!Funky!Stuff!'
/*+
* File: dosb2t.c
* Description:
* dosb2t is a filter.
* dosb2t processes i_files or the standard input.
* dosb2t writes to o_file or standard output.
*
* Converts a DOS binary file to text file.
* Replaces <lf> with <cr><lf>.
*
* Usages:
* dosb2t [-o] <o_file> <i_files>
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
*
* Functions:
*
*
* Audit Trail: $Log: dosb2t.c,v $
* Revision 1.1 85/08/28 08:38:24 mohsen
* original posting to the net
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: dosb2t.c,v 1.1 85/08/28 08:38:24 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef unix
#include "msc3.h"
#endif
/* #defines */
/* external variables */
/* referenced external function declarations */
/* internal function declarations */
PUBLIC VOID dosb2t();
PUBLIC VOID cant_open();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
dosb2t(argc, argv);
}
/*<
* Function:dosb2t
* Description:
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
dosb2t (argc,argv)
INT argc;
CHAR * argv[];
{
FILE * i_fp;
FILE * o_fp;
INT i;
INT c;
i_fp = stdin;
o_fp = stdout;
prog_name = argv[0];
for (i=1; i<argc; ++i) {
if (*argv[i] == '-') {
/* To handle concatenated switches */
INT j;
j=i;
while (*(++argv[j])) {
switch (*argv[j]) {
case 'o':
case 'O':
if ( !(o_fp = fopen(argv[++i], "w")) ) {
cant_open (prog_name, argv[i]);
exit (1);
}
break;
default:
usage();
exit(1);
} /* switch (*argv[j]) */
} /* while (*(++argv[j])) */
} /* if '-' */
else {
if (!(i_fp = fopen (argv[i], "r"))) {
cant_open (prog_name, argv[i]);
exit (1);
}
setmode (fileno(i_fp), O_BINARY);
setmode (fileno(o_fp), O_TEXT);
while (( c = getc (i_fp)) != EOF) {
putc (c, o_fp);
}
fclose (i_fp);
}
} /* for i<argc */
fclose (o_fp);
exit (0);
}
PUBLIC VOID
cant_open (prog_name,filename)
CHAR * prog_name;
CHAR * filename;
{
fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
}
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s [-o] <o_file> <i_files> \n", prog_name);
}
!Funky!Stuff!
echo x - dost2b.c
cat >dost2b.c <<'!Funky!Stuff!'
/*+
* File: dost2b.c
* Description:
* dost2b is a filter.
* dost2b processes i_files or the standard input.
* dost2b writes to o_file or standard output.
*
* Converts a DOS text file to binary file.
* Replaces <cr><lf> to <lf>.
*
* Usages:
* dost2b [-o] <o_file> <i_files>
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
*
* Functions:
*
*
* Audit Trail: $Log: dost2b.c,v $
* Revision 1.1 85/08/28 08:38:28 mohsen
* original posting to the net
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: dost2b.c,v 1.1 85/08/28 08:38:28 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef unix
#include "msc3.h"
#endif
/* #defines */
/* external variables */
/* referenced external function declarations */
/* internal function declarations */
PUBLIC VOID dost2b();
PUBLIC VOID cant_open();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
dost2b(argc, argv);
}
/*<
* Function:dost2b
* Description:
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
dost2b (argc,argv)
INT argc;
CHAR * argv[];
{
FILE * i_fp;
FILE * o_fp;
INT i;
INT c;
i_fp = stdin;
o_fp = stdout;
prog_name = argv[0];
for (i=1; i<argc; ++i) {
if (*argv[i] == '-') {
/* To handle concatenated switches */
INT j;
j=i;
while (*(++argv[j])) {
switch (*argv[j]) {
case 'o':
case 'O':
if ( !(o_fp = fopen(argv[++i], "w")) ) {
cant_open (prog_name, argv[i]);
exit (1);
}
break;
default:
usage();
exit(1);
} /* switch (*argv[j]) */
} /* while (*(++argv[j])) */
} /* if '-' */
else {
if (!(i_fp = fopen (argv[i], "r"))) {
cant_open (prog_name, argv[i]);
exit (1);
}
setmode (fileno(i_fp), O_TEXT);
setmode (fileno(o_fp), O_BINARY);
while (( c = getc (i_fp)) != EOF) {
putc (c, o_fp);
}
fclose (i_fp);
}
} /* for i<argc */
fclose (o_fp);
exit (0);
}
PUBLIC VOID
cant_open (prog_name,filename)
CHAR * prog_name;
CHAR * filename;
{
fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
}
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s [-o] <o_file> <i_files> \n", prog_name);
}
!Funky!Stuff!
echo x - expand.c
cat >expand.c <<'!Funky!Stuff!'
/*+
* File: expand.c
* Description:
* Expand mimics Unix's expand. It is not a full implementation.
* Does not support [-tab1,tab2,..,tabn].
*
* Expand is a filter.
* It processes the named files or the standard input.
* It writes to standard output with tabs changed into blanks.
*
* Usages:
* expand [-tabstop] [i_files]
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
* Functions:
*
*
* Audit Trail: $Log: expand.c,v $
* Revision 1.1 85/08/28 08:38:31 mohsen
* original posting to the net
*
* Revision 1.1 85/08/14 13:44:13 mohsen
* Initial revision
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: expand.c,v 1.1 85/08/28 08:38:31 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef unix
#include "msc3.h"
#endif
/* #defines */
/* external variables */
/* referenced external function declarations */
/* internal function declarations */
PUBLIC VOID expand();
PUBLIC VOID tab_putc();
PUBLIC VOID cant_open();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
STATIC INT tabstop;
STATIC INT cpos;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
expand(argc, argv);
}
/*<
* Function:expand
* Description:
* Parses the command line and calls tab_putc.
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
expand (argc,argv)
INT argc;
CHAR * argv[];
{
FILE * i_fp;
FILE * o_fp;
INT i;
INT c;
i_fp = stdin;
o_fp = stdout;
tabstop = 8;
prog_name = argv[0];
for (i=1; i<argc; ++i) {
if (*argv[i] == '-') {
/* To handle concatenated switches */
INT j;
j=i;
while (*(++argv[j])) {
if (isdigit(*(argv[j]))) {
tabstop = atoi(argv[j]);
break;
}
#if 0
switch (*argv[j]) {
case 'o':
case 'O':
if ( !(o_fp = fopen(argv[++i], "w")) ) {
cant_open (prog_name, argv[i]);
exit (1);
}
break;
default:
usage();
exit(1);
} /* switch (*argv[j]) */
#endif
} /* while (*(++argv[j])) */
} /* if '-' */
else {
if (!(i_fp = fopen (argv[i], "r"))) {
cant_open (prog_name, argv[i]);
exit (1);
}
setmode (fileno(i_fp), O_TEXT);
setmode (fileno(o_fp), O_TEXT);
cpos = 0;
while (( c = getc (i_fp)) != EOF) {
tab_putc (c, o_fp);
}
fclose (i_fp);
}
} /* for i<argc */
fclose (o_fp);
exit (0);
}
/*<
* Function:tab_putc
* Description:
* Converts tabs to the correct number of spaces (tabstop).
* tab_putc is recursive.
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
tab_putc (c, o_fp)
INT c;
FILE * o_fp;
{
if (c == '\n') {
cpos = 0;
putc (c, o_fp);
} else if ( c== '\t') {
do {
tab_putc(' ', o_fp);
} while (cpos % tabstop);
}
else {
cpos++;
putc (c, o_fp);
}
}
PUBLIC VOID
cant_open (prog_name,filename)
CHAR * prog_name;
CHAR * filename;
{
fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
}
#if 0
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s [-tabstop] [i_files]\n", prog_name);
}
#endif
!Funky!Stuff!
echo x - fcrc16.c
cat >fcrc16.c <<'!Funky!Stuff!'
/*+
* File: fcrc16
* Description:
* Calculates crc, given a file pointer.
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
*
* Functions:
*
*
* Audit Trail: $Log: fcrc16.c,v $
* Revision 1.1 85/08/28 08:38:33 mohsen
* original posting to the net
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: fcrc16.c,v 1.1 85/08/28 08:38:33 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
/* #defines */
/* external variables */
/* referenced external function declarations */
/* internal function declarations */
/* global variables */
/* static variables */
/*<
* Function:crc16_table
* Description:
*
* * Calculate CRC16 of a file.
* * CRC16 polynomial: x**0 + x**2 + x**15 + x**16 (0xA001)
* * (CCITT polynomial: x**0 + x**5 + x**12 + x**16 (0x8408))
* *
* * D. Hugh Redelmeier 1983 April 15
*
* Mohsen Banan: I don't know how CRCs work yet.
* None of what is to follow is original work.
*
*
* Returns:
*
>*/
#if 0
VOID
crc16_table()
{
register unsigned s, t;
register int i;
printf("unsigned short crctab[256] = {");
for (t=0; ; ) {
if (t%8 == 0)
printf("\n");
s = t;
for (i=8; i--; )
s = s>>1 ^ (s&1? 0xA001 : 0);
printf("\t0x%04x", s);
if (++t == 256)
break;
printf(",");
}
printf("};\n");
}
#endif
unsigned short crctab[256] = {
0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040};
/*<
* Function:fcrc16
* Description:
* The algorithm comes from
* "Byte-wise CRC Calculations" by Aram Perez,
* IEEE Micro June 1983 pp.40-50
*
* Returns:
* VOID
*
>*/
PUBLIC USHORT
fcrc16 (i_fp, prev_crc, p_fsize)
FILE * i_fp;
USHORT prev_crc;
LONG * p_fsize;
{
USHORT crc, x;
INT c;
LONG fsize;
crc = prev_crc;
fsize = 0L;
while ((c=getc(i_fp)) != EOF) {
/* these are really the same.
* crc = crctab[(crc^c)&0xff] ^ crc>>8;
*/
x = (c^crc) & 0xFF;
crc >>= 8;
crc ^= crctab[x];
++fsize;
}
rewind(i_fp); /* I don't like side effects */
*p_fsize = fsize;
return (crc);
}
!Funky!Stuff!
echo x - hxd.c
cat >hxd.c <<'!Funky!Stuff!'
/*+
* File: hxd
* Description:
* hxd, Hexadecimal dump is similar unix's "od -x"
* Displays the contents of a file in hexadecimal.
* If a byte is printable, it is also printed.
* format of output is :
* dec_add:hex_add word word word word word word word word string
* where:
* dec_add == Start address for that line in decimal.
* hex_add == Start address for that line in hex.
* word == Representation of two bytes in hex. Two characters
* for each byte. First two characters in "word" represent
* the byte that was read sooner.
* string == If the character is printable, it is printed.
* Otherwise a '.' is printed. '.'is printed as '.'.
* For each in put file name of the file is first emited.
* file: <i_file>
* last line for each input file is length of the file in
* "dec_add:hex_add" format.
*
* Usages:
* hxd [-o] <o_file> <i_files>
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
*
* Functions:
*
*
* Audit Trail: $Log: hxd.c,v $
* Revision 1.1 85/08/28 08:38:36 mohsen
* original posting to the net
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: hxd.c,v 1.1 85/08/28 08:38:36 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#ifdef unix
#include "msc3.h"
#endif
/* #defines */
/* external variables */
/* referenced external function declarations */
/* internal function declarations */
PUBLIC VOID hxd();
PUBLIC VOID hxdump();
PUBLIC VOID cant_open();
PUBLIC VOID printisc();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
hxd(argc, argv);
}
/*<
* Function:hxd
* Description:
* Parses the command line and calls hxdump.
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
hxd (argc,argv)
INT argc;
CHAR * argv[];
{
FILE * i_fp;
FILE * o_fp;
INT i;
prog_name = argv[0];
i_fp = stdin;
o_fp = stdout;
for (i=1; i<argc; ++i) {
if (*argv[i] == '-') {
/* To handle concatenated switches */
INT j;
j=i;
while (*(++argv[j])) {
switch (*argv[j]) {
case 'o':
case 'O':
if ( !(o_fp = fopen(argv[++i], "w")) ) {
cant_open(prog_name, argv[i]);
exit(1);
}
break;
default:
usage();
exit(1);
} /* switch (*argv[j]) */
} /* while (*(++argv[j])) */
} /* if '-' */
else {
if (!(i_fp = fopen (argv[i], "r"))) {
cant_open (prog_name, argv[i]);
exit (1);
}
fprintf (o_fp, "file: %s", argv[i]);
setmode (fileno(i_fp), O_BINARY);
setmode (fileno(o_fp), O_TEXT);
hxdump (i_fp, o_fp);
fclose (i_fp);
}
} /* for i<argc */
fclose (o_fp);
exit (0);
}
/*<
* Function:HX_DUMP
* Description:
*
* Arguments:
*
* Returns:
*
* Side Effects:
*
* Calls:
*
>*/
PUBLIC VOID
hxdump (i_fp, o_fp)
FILE * i_fp;
FILE * o_fp;
{
#define BYTESPERLINE 16
LONG i = 0L;
INT c;
INT chars[BYTESPERLINE];
INT j=0;
INT k;
while ((c = getc (i_fp)) != EOF) {
if (! (i % BYTESPERLINE)) {
if (i) {
j=0;
fprintf (o_fp, " ");
printisc (o_fp,chars, BYTESPERLINE);
}
fprintf (o_fp, "\n%07ld:%07lx", i,i );
}
if (!(i++ & 1)) {
putc (' ', o_fp);
}
fprintf (o_fp, "%02x", c);
chars[j++] = c;
}
if (k = (i % BYTESPERLINE)) {
INT jj;
k = BYTESPERLINE - k;
for (jj=0; jj < (5*k/2) ;++jj) {
putc(' ', o_fp);
}
}
fprintf (o_fp, " ");
printisc (o_fp, chars, BYTESPERLINE);
fprintf (o_fp, "\n%07ld:%07lx\n", i,i);
}
PUBLIC VOID
cant_open (prog_name,filename)
CHAR * prog_name;
CHAR * filename;
{
fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
}
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s [-o] <o_file> <i_file> \n", prog_name);
}
PUBLIC VOID
printisc (o_fp, chars, length)
FILE * o_fp;
INT chars[];
INT length;
{
INT i;
for (i=0; i<length; ++i) {
if (isprint (chars[i])) {
putc (chars[i], o_fp);
} else {
putc ('.', o_fp);
}
}
}
!Funky!Stuff!
echo x - sarch.c
cat >sarch.c <<'!Funky!Stuff!'
/*+
* File: SARCH
* Description:
* This is a simple archive utility program.
* Sarch tries to only rely on the C stdio library functions.
* When transferring multiple files between two machines that only have a
* single file transfer utility, sarch becomes handy. Multiple files
* are converted to a sinle file on one end, transfered to the other
* machine and extracted to the original files at the destination.
* System dependent features are very few, keeping it simple
* and portable. Efficiency is sacrificed for portability.
* CRCs are computed when updateing and when extracting.
*
* Usage:
* sarch -{m,u,x,a,t} archname file1 .. filen
* -m Print file names within the archive.
* -u Add or update files to the archive.
* -x Extract files from archive.
* -a Extract all files from the rachive.
* -t PCDOS related. When extracting, test mode is set.
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
*
* Functions:
*
* Sarch relies on the archive manipulating functions:
* ar_open(), ar_close()
* ar_get(), ar_put(), ar_seek().
* ar_get, gets (extracts) a file from the archive.
* ar_put, puts (adds) a file to the archive.
*
*
* Audit Trail: $Log: sarch.c,v $
* Revision 1.1 85/08/28 08:38:52 mohsen
* original posting to the net
*
* Revision 1.1 85/08/13 17:30:27 mohsen
* Initial revision
*
* Revision 1.2 85/04/25 10:27:22 mohsen
* In this version sarch was working fine with the -a and -u options.
*
* Revision 1.1 85/04/19 16:24:43 mohsen
* Initial revision
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: sarch.c,v 1.1 85/08/28 08:38:52 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
#include <fcntl.h>
#ifdef unix
#include "msc3.h"
#endif
/* #defines */
#define AR_BSTR "<archive>"
#define AR_ESTR "<archive>"
/*
* All fileds of ARCH_HDR are strings (0 terminated),
* All fields are left justified.
*/
typedef struct {
CHAR ar_bstr[16]; /* begining archive string */
CHAR fname[16];
CHAR fsize[8];
CHAR fcrc[8];
CHAR ar_estr[16]; /* end archive string */
} ARCH_HDR;
/* external variables */
/* referenced external function declarations */
EXTERN USHORT fcrc16();
/* internal function declarations */
PUBLIC VOID sarch();
PUBLIC FILE * ar_open();
PUBLIC INT ar_close();
PUBLIC SUCC_FAIL ar_put();
PUBLIC SUCC_FAIL ar_get();
PUBLIC SUCC_FAIL ar_seek();
LOCAL VOID wr_hdr();
LOCAL SUCC_FAIL rd_hdr();
LOCAL VOID fld2str();
PUBLIC VOID cpf();
PUBLIC VOID cant_open();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
STATIC ARCH_HDR gw_hdr; /* generic write archive header */
STATIC ARCH_HDR gr_hdr; /* generic read archive header */
STATIC BOOL txt_mode_flag;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
sarch(argc, argv);
}
/*<
* Function:SARCH
* Description:
* Parses the command line and relies on archive manipulating functions to do
* what it should do.
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
sarch (argc,argv)
INT argc;
CHAR * argv[];
{
FILE * ar_fp;
BOOL add_flag;
BOOL xt_flag;
BOOL xt_all_flag;
INT i;
add_flag = xt_flag = xt_all_flag = txt_mode_flag = FALSE;
ar_fp = stdout;
prog_name = argv[0];
sprintf (gw_hdr.ar_bstr, "%-15s", AR_BSTR);
sprintf (gw_hdr.ar_estr, "%-15s", AR_ESTR);
for (i=1; i<argc; ++i) {
if (*argv[i] == '-') {
/* To handle concatenated switches */
INT j;
j=i;
while (*(++argv[j])) {
switch (*argv[j]) {
case 'u':
case 'U':
/*
* add or update a file to the archive
*/
if (!(ar_fp = ar_open (argv[++i], "w"))) {
cant_open(prog_name, argv[i]);
exit (1);
}
add_flag = TRUE;
break;
case 'x':
case 'X':
/*
* Extract a file from the archive.
*/
if (!(ar_fp = ar_open (argv[++i], "r"))) {
cant_open(prog_name,argv[i]);
exit(1);
}
xt_flag = TRUE;
break;
case 'a':
case 'A':
/*
* Extract all files with in this archive
*/
if (!(ar_fp = ar_open (argv[i+1], "r"))) {
cant_open(prog_name,argv[i]);
exit(1);
}
xt_all_flag = TRUE;
break;
case 't':
case 'T':
txt_mode_flag = TRUE;
break;
default:
usage();
exit(1);
} /* switch (*argv[j]) */
} /* while (*(++argv[j])) */
} /* if '-' */
else if (ar_fp == stdout) {
/*
* This is equivalent to "-u" option, ar_fp is stdout.
*/
add_flag = TRUE;
}
else {
/*
* the rest of command line arguments are assumed to be file names.
*/
if (add_flag) {
ar_put (ar_fp, &gw_hdr,argv[i]);
}
else if (xt_flag) {
ar_seek (ar_fp, &gr_hdr, argv[i]);
ar_get (ar_fp,&gr_hdr);
}
else if (xt_all_flag) {
while ( ar_seek (ar_fp, &gr_hdr,(CHAR *) NULL) == SUCCESS ) {
ar_get (ar_fp, &gr_hdr);
}
}
else {
/*
OOPS();
*/
}
}
} /* for i<argc */
ar_close (ar_fp);
exit (0);
}
/*<
* Function:ar_open
* Description:
* Opens an archive directory.
*
* Returns:
* Same as fopen.
*
*
>*/
PUBLIC FILE *
ar_open(path, type)
CHAR * path;
CHAR * type;
{
FILE * fp;
if ( fp=fopen(path,type) ) {
setmode (fileno(fp), O_BINARY);
}
return (fp);
}
/*<
* Function:ar_close
* Description:
* Closes an archive file
*
* Returns:
* same as fclose.
*
>*/
PUBLIC INT
ar_close(ar_fp)
FILE * ar_fp;
{
return (fclose(ar_fp));
}
/*<
* Function: ar_put
* Description:
* Puts the contents of the file specified in "path" into the archive.
* Archive header is written prior to copying the file.
*
* Returns:
* SUCCESS:
* No problems.
* FAIL:
* Couldn't open the file that it is supposed to put it in.
*
>*/
PUBLIC SUCC_FAIL
ar_put(ar_fp, p_ar_hdr, path)
FILE * ar_fp;
ARCH_HDR * p_ar_hdr;
CHAR * path;
{
FILE * fp;
SUCC_FAIL retval;
LONG fsize;
USHORT crc;
retval = SUCCESS;
if (!(fp = fopen(path, "r"))) {
cant_open (prog_name, path);
retval = FAIL;
} else {
setmode (fileno(fp), O_BINARY);
crc = fcrc16(fp, (USHORT)0, &fsize);
rewind(fp);
sprintf (p_ar_hdr->fsize, "%-7ld", fsize);
sprintf (p_ar_hdr->fcrc, "%-7x", (int)crc);
sprintf (p_ar_hdr->fname, "%-15s", path);
wr_hdr(ar_fp, p_ar_hdr);
cpf (fp, ar_fp, fsize);
fclose(fp);
}
return (retval);
}
/*<
* Function:ar_get
* Description:
* Gets (extracts) the contents of a file from the archive.
* and stores it in the file specified in the archive header.
* ar_get is to be invoked after the execution of ar_seek.
*
* Returns:
* SUCCESS:
* Every thing went fine.
* FAIL:
* Couldn't open the file.
*
*
>*/
PUBLIC SUCC_FAIL
ar_get(ar_fp, p_ar_hdr)
FILE * ar_fp;
ARCH_HDR * p_ar_hdr;
{
FILE * fp;
SUCC_FAIL retval;
LONG fsize;
LONG nfsize;
USHORT crc;
USHORT ncrc;
UINT int_crc;
retval = SUCCESS;
if (!(fp = fopen(p_ar_hdr->fname, "w+"))) {
cant_open (prog_name, p_ar_hdr->fname);
retval = FAIL;
} else {
setmode(fileno(fp), O_BINARY);
sscanf (p_ar_hdr->fsize, "%ld", &fsize);
cpf((FILE *)ar_fp, fp, fsize);
rewind(fp);
ncrc = fcrc16(fp, (USHORT)0, &nfsize);
sscanf (p_ar_hdr->fcrc, "%x", &int_crc);
crc = int_crc;
if ( (crc != ncrc) || (fsize != nfsize) ) {
retval = FAIL;
fprintf(stderr, "%s: Problem extacting %s size=%ld, crc=%x\n",
prog_name, p_ar_hdr->fname, fsize, (int)crc);
fprintf(stderr, "%s: Problem extacting %s nsize=%ld, ncrc=%x\n",
prog_name, p_ar_hdr->fname, nfsize, (int)ncrc);
}
fclose(fp);
}
return (retval);
}
/*<
* Function: ar_seek
* Description:
* If path is NULL, the current archive header is read into
* p_ar_hdr.
* Otherwise, the archive is searched for the specified file
* name addressed by path.
*
* Returns:
* SUCCESS if found.
* FAIL if not found, or problem.
*
*
>*/
LOCAL SUCC_FAIL
ar_seek(ar_fp, p_ar_hdr, path)
FILE * ar_fp;
ARCH_HDR * p_ar_hdr;
CHAR * path;
{
SUCC_FAIL retval;
retval = SUCCESS;
if (!path ) {
/* then get it any way */
retval = rd_hdr(ar_fp, p_ar_hdr);
} else {
}
return (retval);
}
/*<
* Function:wr_hdr
* Description:
* Copy the contents of ARCH_HDR to the archive header.
* See rd_hdr for the file archive header picture.
*
* Returns:
* VOID
*
>*/
LOCAL VOID
wr_hdr (ar_fp, p_ar_hdr)
FILE * ar_fp;
ARCH_HDR * p_ar_hdr;
{
fprintf (ar_fp , "%-15s", p_ar_hdr->ar_bstr);
fprintf (ar_fp , "%-15s", p_ar_hdr->fname);
fprintf (ar_fp , "%-7s", p_ar_hdr->fsize);
fprintf (ar_fp , "%-7s", p_ar_hdr->fcrc);
fprintf (ar_fp , "%-15s", p_ar_hdr->ar_estr);
putc ('\n',ar_fp);
}
/*<
* Function:rd_hdr
* Description:
* Reads a header and fills up the ARCH_HDR.
*
0 1 2 3 4 5 6
0123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890
b b b b b
ar_bstr fname fsize fcrc ar_estr
*
* Returns:
* SUCCESS:
* FAIL:
* archive header is bad.
*
*
>*/
LOCAL SUCC_FAIL
rd_hdr (ar_fp, p_ar_hdr)
FILE * ar_fp;
ARCH_HDR * p_ar_hdr;
{
SUCC_FAIL retval;
CHAR hdr_line[256];
INT i;
retval = SUCCESS;
if (!fgets (hdr_line, 255,ar_fp)) {
retval = FAIL;
} else {
fld2str (&hdr_line[0], p_ar_hdr->ar_bstr, 15);
for (i=15; i<30; ++i) {
if ( hdr_line[i] != ' ') {
p_ar_hdr->fname[i-15] = hdr_line[i];
} else {
break;
}
}
p_ar_hdr->fname[i-15] = '\0';
fld2str (&hdr_line[30], p_ar_hdr->fsize, 7);
fld2str (&hdr_line[37], p_ar_hdr->fcrc, 7);
fld2str (&hdr_line[43], p_ar_hdr->ar_estr, 15);
}
return (retval);
}
LOCAL VOID
fld2str ( fld, str, size)
CHAR * fld;
CHAR * str;
INT size;
{
INT i;
for (i=0; i<size; ++i) {
*str++ = *fld++;
}
*str = '\0';
}
/*<
* Function:cpf
* Description:
* Copy the first <fsize> bytes of <src_fp> to <dst_fp>
*
* Returns:
* VOID
*
* Side Effects:
* Both src_fp and dst_fp characters pointers are moved.
*
>*/
LOCAL VOID
cpf (src_fp, dst_fp, fsize)
FILE * src_fp;
FILE * dst_fp;
LONG fsize;
{
LONG i;
for (i=0; i<fsize; ++i) {
putc(getc(src_fp), dst_fp);
}
}
PUBLIC VOID
cant_open (prog_name,filename)
CHAR * prog_name;
CHAR * filename;
{
fprintf (stderr, "%s :can not open %s \n", prog_name, filename);
}
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s [-u] [-x] <filename> \n", prog_name);
}
!Funky!Stuff!
echo x - which.c
cat >which.c <<'!Funky!Stuff!'
/*+
* File: which.c
* Description:
* Tries to mimic Unix's which as closely as possible.
*
* Usages:
* which <i_files>
*
*
* Author: Mohsen Banan.
*
* This program is public domain software, no warranty intended or
* implied.
* General permission to copy or modify, but not for profit, is
* hereby granted.
*
* Functions:
*
*
* Audit Trail: $Log: which.c,v $
* Revision 1.1 85/08/28 08:38:54 mohsen
* original posting to the net
*
*
*
-*/
#ifdef RCS_VER
static char *rcs = "$Header: which.c,v 1.1 85/08/28 08:38:54 mohsen Exp $";
#endif
/* #includes */
#include "mbstd.h"
#include <stdio.h>
/* #defines */
#ifdef BSD4_2
#define strchr index
#endif
/* external variables */
/* referenced external function declarations */
EXTERN char *getenv();
EXTERN char *strchr();
EXTERN char *strcat();
/* internal function declarations */
PUBLIC VOID which();
STATIC CHAR * get_head();
STATIC BOOL is_runable();
STATIC VOID usage();
/* global variables */
/* static variables */
STATIC CHAR * prog_name;
INT
main (argc, argv)
INT argc;
CHAR * argv[];
{
which(argc, argv);
}
/*<
* Function:which
* Description:
*
* Returns:
* VOID
*
>*/
PUBLIC VOID
which (argc,argv)
INT argc;
CHAR * argv[];
{
INT i;
CHAR * head, * nxt_head; /* head concept is a-la Csh */
BOOL end_of_path;
BOOL not_in_path;
STATIC CHAR file_buf[256];
STATIC CHAR path_buf[512];
CHAR * orig_path;
prog_name = argv[0];
if (argc < 2) {
usage();
exit(1);
}
if ((orig_path = getenv("PATH")) == NULL) {
orig_path = ".";
}
for (i=1; i<argc; ++i) {
end_of_path = FALSE;
not_in_path = TRUE;
strcpy (path_buf, orig_path);
nxt_head = head = path_buf;
while ( ! end_of_path ) {
nxt_head = get_head (head);
if ( nxt_head == NULL) {
end_of_path = TRUE;
} else {
*nxt_head = '\0';
}
#ifdef unix
sprintf (file_buf, "%s/%s",(*head ? head:"."), argv[i]);
#endif
#ifdef MSDOS
sprintf (file_buf, "%s\\%s",(*head ? head:"."), argv[i]);
#endif
head = ++nxt_head;
if ( is_runable(file_buf) ) {
printf ("%s\n", file_buf);
not_in_path = FALSE;
}
}
if ( not_in_path ) {
printf ("No %s in %s\n", argv[i], orig_path);
}
} /* for i<argc */
exit (0);
}
STATIC VOID
usage ()
{
fprintf (stderr, "Usage: %s cmd [cmd, ..]\n", prog_name);
}
STATIC CHAR *
get_head (head)
CHAR * head;
{
#ifdef unix
return (strchr( head, ':'));
#endif
#ifdef MSDOS
return (strchr( head, ';'));
#endif
}
STATIC BOOL
is_runable (file_buf)
CHAR * file_buf;
{
BOOL ret_val;
CHAR * name, * root_name; /* root is as defined by Csh */
ret_val = FALSE;
#ifdef unix
if ( access(file_buf, 1) == 0 ) {
ret_val = TRUE;
}
#endif
#ifdef MSDOS
for (root_name=file_buf; *root_name; ++root_name);
name = strcat(file_buf, ".com");
if ( access(name, 0) == 0 ) {
ret_val = TRUE;
}
else {
*root_name = '\0';
name = strcat(file_buf, ".exe");
if ( access(name, 0) == 0 ) {
ret_val = TRUE;
}
else {
*root_name = '\0';
name = strcat(file_buf, ".bat");
if ( access(name, 0) == 0 ) {
ret_val = TRUE;
}
}
}
printf ("\n %s \n", name);
#endif
return (ret_val);
}
!Funky!Stuff!
--
!uw-beaver!tikal!mohsen Mohsen Banan
Teltone Corporation 11811 93rd Ave. N.E. #304
P.O. Box 657 Kirkland, Wa 98033 USA
Kirkland, Wa 98033 USA tel: +1 (206) 821-8560
tel: +1 (206) 827-9626
More information about the Comp.sources.unix
mailing list