|
|
researchv8 Dan Cross
/*
* Package to maintain the temporary file.
*/
#include <stdio.h>
#include <signal.h>
#include "letter.h"
#include "mail.h"
#include "string.h"
/* imports */
extern char *mktemp();
extern int panic();
/* globals */
static letter let[NLETTERS];
#define TMPNAME "/tmp/maXXXXX"
static char tmpfile[sizeof(TMPNAME)];
static FILE *tfp;
static letter *lastp;
#define ASSERT(x,y) if(!(x)) panic(y)
void
inittmp()
{
/* make temp file */
(void)strcpy(tmpfile, TMPNAME);
(void)mktemp(tmpfile);
(void)unlink(tmpfile);
close(creat(tmpfile, 0600));
chown(tmpfile, getuid(), getgid());
tfp = fopen(tmpfile, "r+");
if (tfp == NULL)
panic("mail: can't open tempfile");
}
void
releasetmp()
{
if (tfp != NULL)
fclose(tfp);
unlink(tmpfile);
}
/*
* Modes are:
* "w" to write a letter
* "r" to read a letter
* "ru" to read only undeleted letters
*/
letter *
lopen(n, mode)
int n;
char *mode;
{
letter *lp, *rv = NULL;
if (n >= NLETTERS)
return NULL;
lp = &let[n];
if (strcmp(mode, "w")==0) {
lp->status = L_USED;
(void)fseek(tfp, 0L, 2);
lp->address = ftell(tfp);
lp->offset = lp->size = 0;
rv = lp;
} else if (strcmp(mode, "r")==0) {
if (lp->status & L_USED) {
lp->offset = 0;
(void)fseek(tfp, lp->address, 0);
rv = lp;
}
} else if (strcmp(mode, "ru")==0) {
if ((lp->status & L_USED) && !(lp->status & L_DELETED)) {
lp->offset = 0;
(void)fseek(tfp, lp->address, 0);
rv = lp;
}
}
lastp = rv;
return rv;
}
extern char *
lgets(bp, len, lp)
char *bp;
int len;
letter *lp;
{
char *rv;
ASSERT(lp->status & L_USED, "tmpfile botch");
if (lp != lastp)
(void)fseek(tfp, lp->address+lp->offset, 0);
if (lp->offset >= lp->size)
return NULL;
if (lp->offset+len > lp->size)
len = lp->size - lp->offset + 1;
rv = fgets(bp, len, tfp);
ASSERT(rv != NULL, "tmpfile botch");
lp->offset = ftell(tfp) - lp->address;
lastp = lp;
return bp;
}
extern void
lputs(bp, lp)
char *bp;
letter *lp;
{
int rv;
ASSERT(lp->status & L_USED, "tmpfile botch");
if (lp != lastp)
(void)fseek(tfp, lp->address+lp->offset, 0);
rv = fputs(bp, tfp);
ASSERT(rv != EOF, "can't write to /tmp");
lp->size = lp->offset = ftell(tfp) - lp->address;
lastp = lp;
}
extern void
lputc(c, lp)
char c;
letter *lp;
{
char rv;
ASSERT(lp->status & L_USED, "tmpfile botch");
if (lp != lastp)
(void)fseek(tfp, lp->address+lp->offset, 0);
rv = fputc(c, tfp);
ASSERT(rv != EOF, "can't write to /tmp");
lp->size = lp->offset = ftell(tfp) - lp->address;
lastp = lp;
}
extern long
ltell(lp)
letter *lp;
{
ASSERT(lp->status & L_USED, "tmpfile botch");
return lp->offset;
}
extern long
lsize(lp)
letter *lp;
{
ASSERT(lp->status & L_USED, "tmpfile botch");
return lp->size;
}
extern int
letseek(lp, off)
letter *lp;
long off;
{
ASSERT(lp->status & L_USED, "tmpfile botch");
lp->offset = off < lp->size ? off : lp->size - 1;
lastp = NULL;
return 0;
}
extern int
ldelete(n)
int n;
{
ASSERT(n>= 0 && n < NLETTERS && (let[n].status & L_USED), "tmpfile botch");
let[n].status |= L_DELETED;
return 1;
}
extern int
lundelete(n)
int n;
{
ASSERT(n>= 0 && n < NLETTERS && (let[n].status & L_USED), "tmpfile botch");
let[n].status &= ~L_DELETED;
return 1;
}
extern int
copyto(fp, lp, onatty, escape)
FILE *fp;
letter *lp;
int onatty;
int escape;
{
char buf[FROMLINESIZE];
while (fgets(buf, FROMLINESIZE, fp)!=NULL) {
if (onatty && buf[0]=='.' && buf[1]=='\n' && buf[2]=='\0')
break;
if (escape && strncmp(buf, FROM, FSIZE)==0)
lputc('>', lp);
(void)lputs(buf, lp);
}
}
extern int
copyfrom(lp, fp)
letter *lp;
FILE *fp;
{
char buf[FROMLINESIZE];
while (lgets(buf, FROMLINESIZE, lp)!=NULL)
(void)fputs(buf, fp);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.