gibbons@druco.ATT.COM (GibbonsT) (06/09/90)
Here's a problem I've been battling... any pointer would be appreciated. What's the quickest way to concatenate one large file (~100K) to another using Microsoft C under MS_DOS? Write now I'm just opening the two files and reading from one and append to the other, but it is rather slow. The DOS "copy" command can do this much more quickly using "copy A + B" but I can't figure out how to run "copy" from a C program. I've tried calling "copy" with a spawnl() command but that didn't work so i made a batch file that called copy and then tried to spawnl() the batch file, but that didn't work. So, any suggestions? Any I overlooking something extremely obvious? Thanks in advance, Tom Gibbons, gibbons@druco.att.com
silver@xrtll.uucp (Hi Ho Silver) (06/10/90)
In article <4891@druco.ATT.COM> gibbons@druco.ATT.COM (GibbonsT) writes:
$ What's the quickest way to concatenate one large file (~100K) to
$ another using Microsoft C under MS_DOS? Write now I'm just opening
$ the two files and reading from one and append to the other, but it
$ is rather slow. The DOS "copy" command can do this much more
$ quickly using "copy A + B" but I can't figure out how to run
$ "copy" from a C program. I've tried calling "copy" with a
$ spawnl() command but that didn't work so i made a batch file
$ that called copy and then tried to spawnl() the batch file,
$ but that didn't work. So, any suggestions? Any I overlooking
$ something extremely obvious?
As far as trying to invoke a child process, you can't use spawn for
what you're trying:
- you can't spawn copy since it's ain internal command and spawn will
only run .com and .exe commands
- you can't spawn a batch file since it requires command.com
The ways around these are to use tye system() call, which passed
your argument to a copy of the command processor (basically, it comes up
with the equivalent of a spawn to "command /c your-commands-here").
I assume your C solution involved simply reading the files one
character at a time. This is not a good way to do it, since there's a
certain amount of overhead in each read you do and it adds up like crazy.
The way to do it is to find the commands in your implementation of C that
allow you to read and write large blocks at a time. If memory serves,
the Turbo C calls are blockread() and blockwrite(), which will read and
write as much (up to 64K) of a file as you want them to. This speeds
things up tremendously. I'm sure MSC has equivalent calls.
--
/Nikebo \ Nikebo says "Nikebo knows how to post. Just do it."\silver@xrtll/
/---------\_____________________________________________________\----------/
/yunexus!xrtll!silver (L, not 1)\ Hi Ho Silver \ just silver for short /
/Silver: Ever Searching for SNTF \ Life sucks. \ someone buy me a BEER! /
count0@pnet51.orb.mn.org (Roy Silvernail) (06/11/90)
gibbons@druco.ATT.COM (GibbonsT) writes: > > What's the quickest way to concatenate one large file (~100K) to > another using Microsoft C under MS_DOS? [...] > I've tried calling "copy" with a > spawnl() command but that didn't work I think you'll be able to do it with system(). -- Roy M. Silvernail | Imported from Alaska, where Hell really does freeze over! "You'll be lookin' for me on another label!" (here's 3 of 'em...) UUCP: {amdahl!bungia, uunet!rosevax, crash}!orbit!pnet51!count0 ARPA: crash!orbit!pnet51!count0@nosc.mil INET: count0@pnet51.orb.mn.org
toma@tekgvs.LABS.TEK.COM (Tom Almy) (06/11/90)
[The question was how to concatenate files in the fastest manner]. Assuming you want to use stdio calls (using open, read, and write would be fastest) do this FILE *infile, *outfile; #define BUFSIZE 32768 /* or some other large multiple of 512 */ char *cbuf; int count; infile = fopen(sourceFileName,"rb"); /* open in binary mode */ outfile = fopen(concatFileName,"ab"); /* same for destination file */ setbuf(infile,NULL); /* Do your own buffering */ setbuf(outfile,NULL); cbuf = malloc(BUFSIZE); while ((count = fread(cbuf,sizeof(char),BUFSIZE,infile)) > 0) fwrite(cbuf,sizeof(char),count,outfile); free(cbuf); fclose(infile); fclose(outfile); It is important to both specify binary mode (to eliminate the crlf <-> \n translation) and to use a large buffer, which is in turn better done by yourself so a single buffer can be used. Tom Almy toma@tekgvs.labs.tek.com Standard Disclaimers Apply
det@hawkmoon.MN.ORG (Derek E. Terveer) (06/12/90)
In article <4891@druco.ATT.COM> gibbons@druco.ATT.COM (GibbonsT) writes: > > Here's a problem I've been battling... any pointer would be > appreciated. > > What's the quickest way to concatenate one large file (~100K) to > another using Microsoft C under MS_DOS? Write now I'm just opening > the two files and reading from one and append to the other, but it > is rather slow. Its probably slow if you are either copying a character at a time or using a small buffer. Try allocating a large buffer. Here is a set of useful functions that we use in UUPC (you could use the append() function to append the desired file -- see the man page (cp.tex)): #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # cp.tex # cp.c # mv.c # append.c # global.h # reverse_.c # getmem.c # lower.c # stripsla.c # ftrunc.c # This archive created: Tue Jun 12 02:26:22 1990 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'cp.tex'" '(5069 characters)' if test -f 'cp.tex' then echo shar: "will not over-write existing file 'cp.tex'" else sed 's/^X//' << \SHAR_EOF > 'cp.tex' X% @(#) cp.3 +9" X% this is LaTeX X% \input{../../tex/mymacros} X\documentstyle{article} X% \addtolength{\textwidth}{2.5in} X% \addtolength{\textheight}{3in} X% \setlength{\topmargin}{-1.6in} X\begin{document} X\pagestyle{mystyle} X\markboth{CP(3)}{CP(3)} X\begin{description} X\item[NAME] \ X Xcp, mv, append --- copy, move, and append files X X\item[SYNOPSIS] \ X X\begin{em} Xint cp(src,dst) \\ Xint mv(src,dst) \\ Xint append(src,dst) X Xchar *src; \\ Xchar *dst; X X\end{em} X X\item[DESCRIPTION] \ X XThe {\em cp}, {\em mv}, and {\em append} functions provide simple, general-purpose file Xcopy and move capabilities from within a C program. X{\em Mv} and {\em append} are front ends for {\em cp}, which is Xthe workhorse function of the three. XThe {\em src} and {\em dst} arguments are the source and destination path names, Xrespectively, Xof the files to be copied, moved, or appended. XThese path names may be in either MS-DOS or Unix format. XA source or destination name of X"--" is considered to be the standard input or standard output, respectively. X XBy default, {\em cp} copies an entire source file to a destination file, Xdestroying the original destination file in the process; the original source Xfile remains pristine. {\em Mv} does the same thing as {\em cp} but removes Xthe original source file upon {\bf successfully} copying the file. {\em Append}, as its name implies, Xpresets the destination file's file pointer to the end of the file just before Xthe copy is performed, thus causing copied data to be appended to the end of Xthe Xdestination file; the original source file is untouched. X XTo alter the default behaviour of {\em cp}, i.e., copying entire files, Xone must call {\em cp} with the special Xsource file name {\bf CPOFFSET}\footnote{The constant {\bf CPOFFSET} is Xan impossible MS-DOS file name that is defined Xin "global.h".} before calling {\em cp} again with the actual file names to be Xcopied. The changed behaviour of {\em cp}, effected by {\bf CPOFFSET}, remains Xin effect until {\em cp} is called with real file names, after which {\em Xcp}'s Xbehaviour reverts back to the default. XWhen called with {\em CPOFFSET}, X{\em Cp} interprets the {\em dst} argument as two Xfile-offset, seek-type pairs, as follows: X\begin{quote} X\tt X"srcoffset[,seektype] [dstoffset[,seektype]]" X\end{quote} XWhere {\tt srcoffset} is the offset, in bytes, of the source file pointer and X{\tt dstoffset} is the offset, in bytes, of the destination file pointer. X{\tt Seektype} is Xthe type of seek to perform for each of the two file pointers and Xmay be one of X"0", "1", or "2", where "0" indicates an absolute offset (from the beginning of Xthe file), "1" indicates a Xrelative offset (from the current position of the file pointer), and "2" Xindicates an offset from the end of the file.\footnote{These same byte offset Xand seek type Xarguments are passed, without change, to {\em lseek}(2).} XThe brackets are not entered literally, but, rather, indicate that the destination offset, {\tt dstoffset}, is optional, as are the {\tt seektype} arguments. XThe default for all values is zero, i.e., each file pointer is reset to the beginning Xof the file before a copy. Thus, in the absence of an explicit call to {\em Xcp} with {\bf CPOFFSET} Xspecifying the desired file pointer offsets, it is as if one had coded: X\begin{quote} X\tt Xcp(CPOFFSET,"0,0 0,0"); Xcp(src,dst); X\end{quote} X X\item[EXAMPLE] \ X X\begin{quote} X\tt Xchar src[BUFSIZ]; \\ Xchar dst[BUFSIZ]; \\ Xchar dst2[BUFSIZ]; \\ X/* prompt the user for a file name */ \\ Xprintf("Enter source file name: "); \\ Xgets(src); \\ Xtmpnam(dst); \\ X/* copy the source file to a temp file */ \\ Xcp(src,dst); \\ X/* now move the just copied tmp file to another location */ \\ Xprintf("Enter a tmp file name: "); \\ Xgets(dst2); \\ Xmv(dst,dst2); \\ X/* append the file to a log file */ \\ Xappend(dst2,"/usr/users/biffy/mylog"); \\ X/* now copy the source file starting at byte 100 \\ X * to the middle of the dst file */ \\ Xsprintf(dst2,"100 154000"); \\ Xcp(CPOFFSET,dst2); \\ Xcp(src,dst); \\ X\end{quote} X X\item[EXIT STATUS] \ X XSUCCESS (i.e., 0) for success, various non-zero values for failure. X X\item[SEE ALSO] \ X X{\em memavl}(3), X{\em memmax}(3), X{\em chmod}(2), X{\em lseek}(2), X{\em open}(2), X{\em rename}(2), X{\em setmode}(3), X{\em stat}(2), X{\em utime}(2) X X\item[DIAGNOSTICS] \ X Xcp: can't copy {\it src} to itself! \\ Xcp: can't reset stdin! \\ Xcp: can't open {\it src} \\ Xcp: out of memory! \\ Xcp: out of memory! using emergency tiny buffer (64 bytes) \\ Xcp: can't reset stdout! \\ Xcp: can't create {\it dst} \\ Xcp: requested src lseek(x,y) failed! \\ Xcp: requested dst lseek(x,y) failed! \\ Xmv: no such file or directory X X\item[CAVEATS] \ X XIt is possible that the memory allocation scheme employed by {\em cp} may Xnot be very friendly in Xa multi-tasking environment\footnote{E.g. {\em windows}} Xsince it allocates just about every single byte it Xcan get its filthy paws on. {\em Cp} assumes that it is the Xonly process running. X X\item[AUTHORS] \ X XDerek Terveer (det@hawkmoon.MN.ORG) \\ XJoel Melohn (joelm@nightowl.MN.ORG) X X\end{description} X\end{document} SHAR_EOF if test 5069 -ne "`wc -c < 'cp.tex'`" then echo shar: "error transmitting 'cp.tex'" '(should have been 5069 characters)' fi fi echo shar: "extracting 'cp.c'" '(6579 characters)' if test -f 'cp.c' then echo shar: "will not over-write existing file 'cp.c'" else sed 's/^X//' << \SHAR_EOF > 'cp.c' X#define MINOR "@(#) cp.c +55" X#ifdef SCCS X static char *stampcp = "@(#)cp.c 2.4"; X#ifndef NOMINOR X static char *stamp_cp = MINOR; X#endif X#ifdef DEBUG X static char *stamp_cp_debug = "@(#)debug"; X#endif X#endif X#undef MINOR X X/* cp("-",destfile) copies from stdin to destfile. X * cp(srcfile,"-") copies from srcfile to stdout. X * X * Before copying, cp() may be called with special file names that modify its X * future actions: X * X * cp(CPOFFSET,"srcoffset[,seektype][ dstoffset[,seektype]]") X * defaults: 0 SET 0 SET X * X * SEEK_SET = 0 X * SEEK_CUR = 1 X * SEEK_END = 2 X * X * The CPOFFSET is an impossible file name in ms-dos and is defined in global.h. X */ X X#ifdef MSDOS X#include <stdio.h> X#include <stdlib.h> X#include <fcntl.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <io.h> X#include <string.h> X#include <malloc.h> X#include "global.h" X#endif X Xint Xcp(src,dst) X X char *src; X char *dst; X X{ X#ifdef MSDOS X char *buf; X size_t bufsize; X extern int debuglevel; X static long dstoffset = 0L; X static int dstseektype = SEEK_SET; X static char emergency[64]; X int fdst; X char *finaldst; X int fsrc; X boolean fstdin = FALSE; X boolean fstdout = FALSE; X extern char *getmem(); X extern char *lower(); X unsigned minsize; X int oldmode; X char *p; X static char PID = "cp"; X unsign int r; X static long srcoffset = 0L; X static int srcseektype = SEEK_SET; X int st; X struct stat stbuf; X unsign int w; X#else X char cmd[BUFSIZ]; X#endif X char control[32]; X X X#ifdef MSDOS X lower(src); X#ifdef DEBUG X if (debuglevel>2) fprintf(stderr,"%s(%s,%s)\n",PID,src,dst); X#endif X if (strcmp(src,CPOFFSET)==SAME) X then X {char *q; X X#ifdef DEBUG X if (debuglevel>4) fprintf(stderr,"special file: %s\n",src); X#endif X strcpy(control, dst); X if ((p=strchr(control,SPACE))) *p='\0'; X if ((q=strchr(control,COMMA))) *q='\0'; X srcoffset=atol(control); X if (q) srcseektype=atoi(q+1); X if (p++) X then X {if ((q=strchr(p,COMMA))) *q='\0'; X dstoffset=atol(p); X if (q) dstseektype=atoi(q+1); X } X else dstoffset=0L; X#ifdef DEBUG X if (debuglevel>4) fprintf(stderr,"%s: request srcoffset %ld/%d dstoffset %ld/%d\n",PID,srcoffset,srcseektype,dstoffset,dstseektype); X#endif X return(SUCCESS); X } X lower(dst); X if (strcmp(src,dst)==SAME && strcmp(src,"-")!=SAME) X then X {fprintf(stderr,"%s: can't copy %s to itself!\n",PID,src); X return(2); X } X if ((fsrc=open(src,O_BINARY|O_RDONLY))==FAIL) X then X {if (strcmp(src,"-")==SAME) X then X {fsrc=fileno(stdin); X if ((oldmode=setmode(fsrc,O_BINARY))==FAIL) X then X {perror(PID); X fprintf(stderr,"%s: can't reset stdin!\n",PID); X return(FAIL); X } X fstdin=TRUE; X } /* - */ X else X {perror(PID); X fprintf(stderr,"%s: can't open %s\n",PID,src); X return(1); X } /* src is - */ X } /* open src */ X if (!fstdin) fstat(fsrc,&stbuf); X r=strlen(dst); X /* calculate absolute min memory needed for writing path names X */ X if ((p=strrchr(src,SLASH))) X then r=minsize=r+strlen(p)+1; X else r=minsize=r+strlen(src)+2; X /* now calculate desirable min memory X */ X if (fstdin) X then minsize=max(minsize,_memmax()); X else minsize=max(minsize,stbuf.st_size); X /* can this desired min be satisfied by the static buffer? X */ X if (minsize<=sizeof(emergency)) X then X {buf=emergency; X bufsize=sizeof(emergency); X#ifdef DEBUG X if (debuglevel>7) printf("%s: static buffer satisfies memory need, use it instead of getmem(%u)\n",PID,minsize); X#endif X } X else /* no.. must allocate some memory */ X { X#ifdef DEBUG X if (debuglevel>8) X then X {printf("%s: before getmem(): size=%ld",PID,stbuf.st_size); X /* the following statement hangs the PC! The only difference between X * this and the next one (that works) is the leading underscore "_" on X * memavl in the format string... very strange. X * A msc5.1 bug???? X printf(" _memavl()=%u",_memavl()); X */ X printf(" memavl()=%u",_memavl()); X printf(" _memmax()=%u\n",_memmax()); X } X#endif X if (!(bufsize=_memmax()) || X !(buf=getmem((bufsize=min(bufsize,minsize))))) X then X {fprintf(stderr,"%s: out of memory! ",PID); X if (r>sizeof(emergency)) X then X {fputc('\n',stderr); X return(FAIL); X } X fprintf(stderr,"using emergency tiny buffer (%d bytes)\n",sizeof(emergency)); X buf=emergency; X bufsize=sizeof(emergency); X } /* no memory */ X#ifdef DEBUG X if (debuglevel>7) printf("%s: after getmem(): bufsize=%u _memavl()=%u _memmax()=%u\n",PID,bufsize,_memavl(),_memmax()); X#endif X } /* allocate */ X if (strcmp(dst,"-")==SAME) X then X {fdst=fileno(stdout); X if ((oldmode=setmode(fdst,O_BINARY))==FAIL) X then X {perror(PID); X fprintf(stderr,"%s: can't reset stdout!\n",PID); X return(FAIL); X } X fstdout=TRUE; X } /* - */ X else X {/* destination is a directory */ X if (!stat(dst,&stbuf) && stbuf.st_mode&S_IFDIR) X then X {if ((p=strrchr(src,SLASH))) X then sprintf(buf,"%s/%s",dst,p+1); X else sprintf(buf,"%s/%s",dst,src); X finaldst=buf; X } X else finaldst=dst; X if (!dstoffset && dstseektype==SEEK_SET) unlink(finaldst); X if ((fdst=open(finaldst,O_BINARY|O_CREAT|O_WRONLY,0666))==FAIL) X then X {perror(PID); X free(buf); X if (!fstdin) close(fsrc); X fprintf(stderr,"%s: can't create %s\n",PID,finaldst); X return(1); X } X } /* ! stdout */ X if (lseek(fsrc,srcoffset,srcseektype)==FAIL) X then fprintf(stderr,"%s: requested src lseek(%ld,%d) failed!\n",PID,srcoffset,srcseektype); X if (lseek(fdst,dstoffset,dstseektype)==FAIL) X then fprintf(stderr,"%s: requested dst lseek(%ld,%d) failed!\n",PID,dstoffset,dstseektype); X while ((r=read(fsrc,buf,bufsize))>0) X {w=write(fdst,buf,r); X if (w!=r) X then X {perror(PID); X free(buf); X if (!fstdin) close(fsrc); X close(fdst); X return(4); X } X } X free(buf); X#ifdef DEBUG X if (debuglevel>8) printf("%s: after free(): _memavl()=%u, _memmax()=%u\n",PID,_memavl(),_memmax()); X#endif X if (!fstdin) close(fsrc); X if (fstdin) setmode(fsrc,oldmode); X close(fdst); X if (r<0) X then X {perror(PID); X return(5); X } X srcoffset=dstoffset=0L; X srcseektype=dstseektype=SEEK_SET; X return(SUCCESS); X#else X sprintf(cmd,"%s %s %s",PID,src,dst); X return(system(cmd)); X#endif X} /* cp */ SHAR_EOF if test 6579 -ne "`wc -c < 'cp.c'`" then echo shar: "error transmitting 'cp.c'" '(should have been 6579 characters)' fi fi echo shar: "extracting 'mv.c'" '(3755 characters)' if test -f 'mv.c' then echo shar: "will not over-write existing file 'mv.c'" else sed 's/^X//' << \SHAR_EOF > 'mv.c' X#define MINOR "@(#) mv.c +52" X#if defined(SCCS) X static char *stampmv = "@(#)mv.c 2.10"; X#if !defined(NOMINOR) X static char *stamp_mv = MINOR; X#endif X#if defined(DEBUG) X static char *stamp_mv_debug = "@(#)debug"; X#endif X#endif X#undef MINOR X X#if defined(DEBUG) X#include <stdio.h> X#else X#define NULL 0 X#endif X#if defined(MSDOS) X#include <string.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <sys/utime.h> X#include <fcntl.h> X#include "global.h" X#endif X Xint Xmv(src,dst) X X char *src; X char *dst; X X{extern char *append_file_to_path(); X#if !defined(MSDOS) X char cmd[BUFSIZ]; X#endif X#if defined(DEBUG) X extern int debuglevel; X#endif X#if defined(MSDOS) X struct stat dstbuf; X extern char *getmem(); X regist int i; X struct utimbuf mtime; X char *newdst = NULL; X regist char *pd; X regist char *ps; X boolean Rename = FALSE; X struct stat srcbuf; X extern char *reverse_slashes(); X extern char *strip_superfluous_slashes(); X#endif X X#if defined(DEBUG) X if (debuglevel>3) fprintf(stderr,"mv(%s,%s)\n",src,dst); X#endif X X#if defined(MSDOS) X strip_superfluous_slashes(src,FALSE); X strip_superfluous_slashes(dst,FALSE); X X /* source must exist before anything can be done X */ X if (stat(src,&srcbuf)) {perror("mv"); return(FAIL);} X X /* if destination doesn't exist, create a bogus destination file X */ X if (stat(dst,&dstbuf)) X then X {if ((i=open(dst,O_CREAT,S_IWRITE))==FAIL) {perror(dst); return(FAIL);} X fstat(i,&dstbuf); X close(i); X } X X /* We can rename the source file (instead of copying and deleting) if: X * Its a file and both src and dst are on the same device, or X * Its a directory and both src and dst are in the same directory (and X * hence, on the same device X */ X if (srcbuf.st_dev==dstbuf.st_dev) X then X {reverse_slashes(src); X if (srcbuf.st_mode&S_IFREG) X then X {Rename=TRUE; X if (newdst=append_file_to_path(dst,src,dstbuf.st_mode&S_IFDIR)) dst=newdst; X unlink(dst); X } /* file */ X else if (srcbuf.st_mode&S_IFDIR) X then X {reverse_slashes(dst); X if ((ps=strrchr(src,SLASH))) *ps='\0'; X if ((pd=strrchr(dst,SLASH))) *pd='\0'; X if (strcmp(src,dst)==SAME) Rename=TRUE; X if (ps) *ps=SLASH; X if (pd) *pd=SLASH; X if (Rename) rmdir(dst); X } /* dir */ X } /* same device */ X X if (Rename) X then X {i=rename(src,dst); X if (newdst) free(newdst); X return(i); X } X else X {if ((i=cp(src,dst))) return(i); X mtime.modtime=srcbuf.st_mtime; X if (newdst=append_file_to_path(dst,src,dstbuf.st_mode&S_IFDIR)) dst=newdst; X#if defined(DEBUG) X if (debuglevel > 4) printf("dst=`%s'\tnewdst=`%s'\n",dst,newdst); X#endif X if (utime(dst,&mtime)) X then X {if (dstbuf.st_mode&S_IWRITE) X then perror(dst); X else X {chmod(dst,S_IWRITE); X if (utime(dst,&mtime)) perror(dst); X chmod(dst,S_IREAD); X } /* r/o */ X } /* couldn't reset mtime */ X if (newdst) free(newdst); X unlink(src); X } /* cp */ X return(SUCCESS); X#else X sprintf(cmd,"mv %s %s",src,dst); X return(system(cmd)); X#endif X} /* mv */ X Xchar * Xappend_file_to_path(path,file,dir) X X char *path; X char *file; X boolean dir; /* t if path is a dir */ X X{ char *newpath; X char *p; X X if (dir) X then X {if ((p=strrchr(file,SLASH))) ++p; else p=file; /* get basename */ X if (!(newpath=getmem(strlen(path)+1+strlen(p)+1))) X then exit(FAIL); X else X {sprintf(newpath,"%s/%s",path,p); X return(newpath); X } X } /* dst is a dir */ X return(NULL); X} /* append_file_to_path */ SHAR_EOF if test 3755 -ne "`wc -c < 'mv.c'`" then echo shar: "error transmitting 'mv.c'" '(should have been 3755 characters)' fi fi echo shar: "extracting 'append.c'" '(554 characters)' if test -f 'append.c' then echo shar: "will not over-write existing file 'append.c'" else sed 's/^X//' << \SHAR_EOF > 'append.c' X#define MINOR "@(#) append.c +2" X#if defined(SCCS) X static char *stampappend = "@(#)append.c 2.2"; X#ifndef NOMINOR X static char *stamp_append = MINOR; X#endif X#if defined(DEBUG) X static char *stamp_append_debug = "@(#)debug"; X#endif X extern char *stamp_sum_version; X#endif X#undef MINOR X X#include <stdio.h> X#include "global.h" X Xint Xappend(src,dst) X X char *src; X char *dst; X X{ char buf[6]; X extern int cp(); X X sprintf(buf,"0 0,%d",SEEK_END); X cp(CPOFFSET,buf); X return(cp(src,dst)); X} /* append */ SHAR_EOF if test 554 -ne "`wc -c < 'append.c'`" then echo shar: "error transmitting 'append.c'" '(should have been 554 characters)' fi fi echo shar: "extracting 'global.h'" '(3327 characters)' if test -f 'global.h' then echo shar: "will not over-write existing file 'global.h'" else sed 's/^X//' << \SHAR_EOF > 'global.h' X#define MINOR "@(#) global.h +84" X#if defined(SCCS) X static char *stampglobal_h = "@(#)global.h 2.10"; X#if !defined(NOMINOR) X static char *stamp_global_h = MINOR; X#endif X#endif X#undef MINOR X X#include <ctype.h> X X#define ALL -1 X#define ASTERISK '*' X#define AT '@' X#define BACKSLASH '\\' X#define BACKWARD -1 X#define BANG '!' X#define BINARYMODE 'b' X#define BOTH 0 X#define COLON ':' X#define COMMA ',' X#define COMMAND_MODE 0 X#define COMMENT '#' X#define COMPOSE_ESCAPE TILDE X#define COPYFILE "Mail/MailSent" X#define CORRUPT "_Corrupt" X#define CPOFFSET ".offset" /* offset flag for cp() */ X#define CR '\r' X#define CRONTABS "cron/crontabs" X#define CRONLASTTIME "cron/lasttime" X#define CWDSIZE 66 X#define DASH '-' X#define DEADFILE "dead.let" X#define DIGITS "0123456789" X#define DIGITSANDSPACE "0123456789 " X#define DOLLAR '$' X#define DOT '.' X#define DRIVE_SELECT COLON X#define EXISTS 0 X#define FAIL -1 X#define FAILED -1 X#define FALSE 0 X#define FIRST 0 X#define FORWARD "Forward to" X#define GETTYDEFS "gettydefs" X#define GRADE_LP 'p' /* grade for lp files */ X#define GRADE_MAIL 'f' /* grade for mail */ X#define GRADE_NEWS 'u' /* grade for news files */ X#define GRADE_UUTO 'k' /* grade for uuto'd files */ X#define GREATER_THAN '>' X#define HELPFILE "c:/usr/lib/mail/help" X#define H_FORWARD 1 X#define INPUT_MODE 1 X#define KILOBYTE 1024 X#define LAST 1 X#define LEFT_PAREN '(' X#define LESS_THAN '<' X#define LOGFILE "LOGFILE" X#define MAILWIDTH 80 /* max width for headers in mail */ X#define MASTER 1 X#define MAXDOSPATH 140 /* max path name in dos, comprising drive X * prefix, full directory path, and final X * file name X */ X#define MAXLETTERS 400 X#define MAXRANGE 30 X#define MAXREPLIES 100 X#define MAXSEQLEN 6 X#define MBOXFILE "mbox" X#define MEGABYTE 1048576 X#define NEW 3 X#define NONE 0 X#define NOSCROLL 0 X#define PASSWD "passwd" X#define PERCENT '%' X#define PIPE '|' X#define PLUS '+' X#define QUOTE '"' X#define READ 2 X#define READABLE 4 X#define RIGHT_PAREN ')' X#define SAME 0 X#define SBUFSIZ 124 X#define SCROLL 1 X#define SECS_PER_DAY 86400 X#define SECS_PER_HOUR 3600 X#define SEMICOLON ';' X#define SEPCHAR '/' X#define SFILENAME "SEQF" X#define SLASH '/' X#define SLAVE 0 X#define SPACE ' ' X#define STDOUT 2 X#define SUCCESS 0 X#define SYSTEMS "Systems" X#define TAB ' ' X#define TEXTMODE 't' X#define TFILENAME "%.8ld.Tmp" /* nnnnnnnn.Tmp */ X#define TILDE '~' X#define TRUE 1 X#define UNDERSCORE '_' X#define UNREAD 1 X#define WHITE " " /* MUST have a space and a tab! */ X#define WRITABLE 1 X#define XMAILER "X-Mailer: " /* mailer version header */ X#define XQTDIR "_Xqtdir" X#define XREQACK "X-Acknowledgement-To: " /* reqack mail header */ X#define boolean short X#define drivespec(path) (isalpha(*(path)) && *(path+1)==DRIVE_SELECT) X#define fullpath(path) (drivespec(path) && (*(path+2)==SLASH||(*(path+2)==BACKSLASH)) || !drivespec(path) && (*path==SLASH||*path==BACKSLASH)) X#define plural(i) ((i)==1?"":"s") X#define reg register X#define regist register X#define relpath(path) (drivespec(path) && *(path+2)!=SLASH || !drivespec(path) && *path!=SLASH) X#define then X#define unsign unsigned X#define max(x,y) (((x) > (y)) ? (x) : (y)) X#define min(x,y) (((x) < (y)) ? (x) : (y)) SHAR_EOF if test 3327 -ne "`wc -c < 'global.h'`" then echo shar: "error transmitting 'global.h'" '(should have been 3327 characters)' fi fi echo shar: "extracting 'reverse_.c'" '(312 characters)' if test -f 'reverse_.c' then echo shar: "will not over-write existing file 'reverse_.c'" else sed 's/^X//' << \SHAR_EOF > 'reverse_.c' X#define MINOR "@(#) reverse_.c +2" X#ifdef SCCS X static char *stampreverse_slashes = "@(#)"; X#ifndef NOMINOR X static char *stamp_reverse_slashes = MINOR; X#endif X#endif X Xchar *reverse_slashes(s) X Xchar *s; X X{char *p; X X for (p=s; *p; ++p) if (*p=='\\') *p='/'; X return(p); X} /* reverse_slashes */ SHAR_EOF if test 312 -ne "`wc -c < 'reverse_.c'`" then echo shar: "error transmitting 'reverse_.c'" '(should have been 312 characters)' fi fi echo shar: "extracting 'getmem.c'" '(767 characters)' if test -f 'getmem.c' then echo shar: "will not over-write existing file 'getmem.c'" else sed 's/^X//' << \SHAR_EOF > 'getmem.c' X#define MINOR "@(#) getmem.c +20" X#if defined(SCCS) X static char *stampgetmem = "@(#)getmem.c 2.4"; X#ifndef NOMINOR X static char *stamp_getmem = MINOR; X#endif X#if defined(DEBUG) X static char *stamp_getmem_debug = "@(#)debug"; X#endif X#endif X#undef MINOR X X#include <stdio.h> X Xchar * Xgetmem(bytes) X X int bytes; X X{ X#if defined(DEBUG) X extern int debuglevel; X#endif X extern char *malloc(); X char *p; X X#if defined(DEBUG) X if (debuglevel>30) fprintf(stderr,"getmem(%u), ",(unsigned)bytes); X#endif X if (!(p=malloc((unsigned)bytes))) fprintf(stderr,"getmem: can't allocate %u bytes!\n",(unsigned)bytes); X#if defined(DEBUG) X if (debuglevel>40) printf("address returned from malloc = %x\n", p); X#endif X return(p); X} /* getmem */ SHAR_EOF if test 767 -ne "`wc -c < 'getmem.c'`" then echo shar: "error transmitting 'getmem.c'" '(should have been 767 characters)' fi fi echo shar: "extracting 'lower.c'" '(277 characters)' if test -f 'lower.c' then echo shar: "will not over-write existing file 'lower.c'" else sed 's/^X//' << \SHAR_EOF > 'lower.c' X#define MINOR "@(#) lower.c +5" X#ifdef SCCS X static char *stamplower = "@(#)lower.c 2.2"; X#ifndef NOMINOR X static char *stamp_lower = MINOR; X#endif X#endif X X#include <ctype.h> X Xchar *lower(s) X Xchar *s; X X{char *p; X X for (p=s; *p; ++p) *p=tolower(*p); X return(s); X} /* lower */ SHAR_EOF if test 277 -ne "`wc -c < 'lower.c'`" then echo shar: "error transmitting 'lower.c'" '(should have been 277 characters)' fi fi echo shar: "extracting 'stripsla.c'" '(990 characters)' if test -f 'stripsla.c' then echo shar: "will not over-write existing file 'stripsla.c'" else sed 's/^X//' << \SHAR_EOF > 'stripsla.c' X#define MINOR "@(#) stripsla.c +1" X#if defined(SCCS) X static char *stampstrip_superfluous_slashes = "@(#)stripsla.c 1.2"; X#if !defined(NOMINOR) X static char *stamp_strip_superfluous_slashes = MINOR; X#endif X#if defined(DEBUG) X static char *stamp_strip_superfluous_debug = "@(#)debug"; X#endif X#endif X#undef MINOR X X#include "global.h" X X/* Strip multiple superfluous slashes from a path name. X * Dos 2.11 chokes on path names that X * contain concatenated slashes... unix just ignores these. X * X * /usr/spool/uucppublic/receive/root//ihnp4/testfile X * gets converted to: X * /usr/spool/uucppublic/receive/root/ihnp4/testfile X */ X Xchar * Xstrip_superfluous_slashes(path,keep_last_slash) X X char path[]; X boolean keep_last_slash; X X{ X char *p; X char *q; X X for (p=q=path+1; *p; ++p) X {if (*p!=SLASH || *(p-1)!=SLASH) *q++ = *p; X } X if (keep_last_slash && *(p-1)==SLASH) *q++ = SLASH; X *q='\0'; X return(path); X} /* strip_superfluous_slashes */ SHAR_EOF if test 990 -ne "`wc -c < 'stripsla.c'`" then echo shar: "error transmitting 'stripsla.c'" '(should have been 990 characters)' fi fi echo shar: "extracting 'ftrunc.c'" '(2091 characters)' if test -f 'ftrunc.c' then echo shar: "will not over-write existing file 'ftrunc.c'" else sed 's/^X//' << \SHAR_EOF > 'ftrunc.c' X#define MINOR "@(#) ftrunc.c +20" X#if defined(SCCS) X static char *stampftrunc = "@(#)ftrunc.c 2.2"; X#ifndef NOMINOR X static char *stamp_ftrunc = MINOR; X#endif X#if defined(DEBUG) X static char *stamp_ftrunc_debug = "@(#)debug"; X#endif X#endif X#undef MINOR X X#include <stdio.h> X#include <dos.h> X#include <fcntl.h> X#include "global.h" X X/* X * Truncate a file with fileno "handle" to byte "offset" relative to the given X * origin, "org". X */ X Xint Xftrunc(handle,offset,org) X X int handle; X long offset; X int org; X X{ X void far *buf; X#if defined(DEBUG) X extern int debuglevel; X#endif X int errcode; X union REGS inregs; X union REGS outregs; X static char *pid = "ftrunc"; X unsign int written; X X /* X if (_dos_open(path,O_RDWR,&handle)!=0) X then X {perror(pid); X printf("%s: can't open `%s'\n",pid,path); X return(FAIL); X } X#if defined(DEBUG) X if (debuglevel>13) printf("%s: handle=%d\n",pid,handle); X#endif X */ X X /* seek to offset */ X inregs.h.ah = 0x42; X inregs.h.al = org; X inregs.x.bx = handle; X inregs.x.cx = (offset & 0xFFFF0000) >> 16; X inregs.x.dx = offset & 0x0000FFFF; X#if defined(DEBUG) X if (debuglevel>13) printf("%s: offset=%ld, cx=%u dx=%u\n",pid,offset,inregs.x.cx,inregs.x.dx); X intdos(&inregs,&outregs); X#endif X if (errcode=outregs.x.cflag ? outregs.x.ax : 0) X then X {printf("%s: can't seek to %ld from %d, errcode=%d\n",pid,offset,org,errcode); X return(errcode); X } X#if defined(DEBUG) X if (debuglevel>13) printf("%s: seek successful; now at dx=%u ax=%u\n",pid,outregs.x.dx,outregs.x.ax); X#endif X X /* now truncate the file */ X if (_dos_write(handle,buf,(unsigned)0,&written)!=0) X then X {perror(pid); X printf("%s: can't write to file\n",pid); X return(FAIL); X } X#if defined(DEBUG) X if (debuglevel>13) printf("%s: bytes written=%u\n",pid,written); X#endif X X /* close file */ X /* X if (_dos_close(handle)!=0) X then X {perror(pid); X printf("%s: can't close file\n",pid); X return(FAIL); X } X */ X return(SUCCESS); X} /*ftrunc*/ SHAR_EOF if test 2091 -ne "`wc -c < 'ftrunc.c'`" then echo shar: "error transmitting 'ftrunc.c'" '(should have been 2091 characters)' fi fi exit 0 # End of shell archive -- Derek Terveer det@hawkmoon.MN.ORG