/* roll.c - sequetial read/write cache programs * This is the part of the Tar program (see file tar.c) * Author: T.V.Shaporev * Prepared for release 19 Oct 1990 * Called by store() (see file store.c) */ #include "sysup.h" #include #ifdef TRACE extern FILE *myout; # define Printf (void)printf #endif #ifdef MSDOS # include # include # include # include # ifdef __TURBOC__ # include # define write _write # define read _read # else # include # include # endif # include # define CREATE(x) open((x),O_CREAT+O_TRUNC+O_RDWR+O_BINARY,S_IREAD+S_IWRITE) # define FREE(x) free(x) #else # define CREATE(x) creat((x),0600) # define FREE(x) free((char *)(x)) int strlen(); char *malloc(), *strncpy(), *strncat(), *getenv(), *mktemp(); int creat(), read(), write(), close(), unlink(); long lseek(); void free(); #endif #ifdef UNIX # define TMPDIR "/usr/tmp" # define DIR "/" # define DEV '\0' # define MAXFNAME 512 /* Analagous to MAXNAMSIZ */ #endif #ifdef VMS # define TMPDIR "SYS$SCRATCH:" # define DIR "]" # define DEV ':' # define MAXFNAME 512 /* ??? */ #endif #ifdef MSDOS # define TMPDIR "" # define DIR "\\" # define DEV ':' # define MAXFNAME MAXPATH #endif #define MAXPAGE 64 /* max cash is 0.5M */ #define PAGESIZE 8192 /* Be careful !!! */ typedef struct { unsigned char * page[MAXPAGE]; int poz, npage, maxpage; char name[MAXFNAME+1]; int handle; } roll; #include "roll.h" static roll *r = (roll *)0; int newroll(templ) char *templ; { register i; char *e; if (r) return 0; r = (roll *)malloc(sizeof(roll)); if (!r) return -1; (r->page)[0] = (unsigned char *)malloc(PAGESIZE); if (!((r->page)[0])) { FREE((char *)r); return -1; } for (i=1; ipage)[i] = (unsigned char *)0; r->maxpage = MAXPAGE - 1; r->npage = 0; r->poz = 0; if ((e = getenv("TMP")) == (char *)0) { (void)strncpy(r->name, TMPDIR, MAXFNAME); } else { (void)strncpy(r->name, e, MAXFNAME); } #ifndef VMS i = strlen(r->name) - 1; if (r->name[i]!= *DIR # ifdef DEV && r->name[i]!=DEV # endif ) (void)strncat(r->name,DIR,MAXFNAME); #endif (void)mktemp(strncat(r->name, templ, MAXFNAME)); r->handle = -1; #ifdef TRACE Printf("new roll: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif return 0; } void delroll() { register i; if (!r) return; #ifdef TRACE Printf("del roll: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif for (i=0; ipage)[i]; i++) FREE((r->page)[i]); if (r->handle >= 0) { (void)close (r->handle); (void)unlink(r->name); } r = (roll *)0; } int rewroll(flread) int flread; { #ifdef TRACE Printf("rew roll: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif if (r->handle >= 0 && r->npage >= r->maxpage) { if (write(r->handle,(char*)((r->page)[r->maxpage]),PAGESIZE)!=PAGESIZE) return -1; if (lseek(r->handle, 0L, 0) < 0) return -1; if (flread && r->maxpage < 1) { if (read(r->handle, (char*)((r->page)[0]), PAGESIZE) != PAGESIZE) return -1; } } r->npage = 0; r->poz = 0; return 0; } int rputc(i) int i; { register unsigned char *p; if (r->poz >= PAGESIZE) { #ifdef TRACE Printf(" roll 1: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif if (r->npage < r->maxpage) { p = (r->page)[(r->npage)+1]; if (p) { r->npage += 1; } else if (r->handle < 0) { p = (unsigned char *)malloc(PAGESIZE); if (p) { (r->page)[++(r->npage)] = p; r->poz = 0; } else { r->maxpage = r->npage; } } } else { p = (unsigned char *)0; } if (!p) { if (r->handle < 0) { if ((r->handle = CREATE(r->name)) < 0) return EOF; } if (write(r->handle, (char*)((r->page)[r->maxpage]), PAGESIZE) != PAGESIZE) return EOF; } r->poz = 0; #ifdef TRACE Printf(" roll 2: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif } *((r->page)[r->npage] + (r->poz)++) = i; #ifdef TRACE if (r->npage < 0 || r->npage >= MAXPAGE || r->npage > r->maxpage) { (void)fprintf(myout, "Alarm! npage out of range\n"); } if (r->poz < 0 || r->poz > PAGESIZE) { (void)fprintf(myout, "Alarm! poz out of range\n"); } #endif return 0; } int rgetc() { if (r->poz >= PAGESIZE) { #ifdef TRACE Printf(" roll 1: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif if (r->handle >= 0 && (r->npage)+1 >= r->maxpage) { if (read(r->handle, (char*)((r->page)[r->maxpage]), PAGESIZE) != PAGESIZE) { return EOF; } r->npage = r->maxpage; } else { if (r->handle < 0 && r->npage >= MAXPAGE) return EOF; if (!(r->page)[++(r->npage)]) return EOF; } r->poz = 0; #ifdef TRACE Printf(" roll 2: poz = %4d page = %d max = %2d handle = %d\n", r->poz, r->npage, r->maxpage, r->handle); #endif } #ifdef TRACE if (r->npage < 0 || r->npage >= MAXPAGE || r->npage > r->maxpage) { (void)fprintf(myout, "Alarm! npage out of range\n"); } if (r->poz < 0 || r->poz >= PAGESIZE) { (void)fprintf(myout, "Alarm! poz out of range\n"); } #endif return *((r->page)[r->npage] + (r->poz)++); }