|
|
1.1 ! root 1: /* ! 2: * Package to maintain the temporary file. ! 3: */ ! 4: #include <stdio.h> ! 5: #include <signal.h> ! 6: #include "letter.h" ! 7: #include "mail.h" ! 8: #include "string.h" ! 9: ! 10: /* imports */ ! 11: extern char *mktemp(); ! 12: extern int panic(); ! 13: ! 14: /* globals */ ! 15: static letter let[NLETTERS]; ! 16: ! 17: #define TMPNAME "/tmp/maXXXXX" ! 18: static char tmpfile[sizeof(TMPNAME)]; ! 19: ! 20: static FILE *tfp; ! 21: static letter *lastp; ! 22: ! 23: #define ASSERT(x,y) if(!(x)) panic(y) ! 24: ! 25: void ! 26: inittmp() ! 27: { ! 28: /* make temp file */ ! 29: (void)strcpy(tmpfile, TMPNAME); ! 30: (void)mktemp(tmpfile); ! 31: (void)unlink(tmpfile); ! 32: close(creat(tmpfile, 0600)); ! 33: chown(tmpfile, getuid(), getgid()); ! 34: tfp = fopen(tmpfile, "r+"); ! 35: if (tfp == NULL) ! 36: panic("mail: can't open tempfile"); ! 37: } ! 38: ! 39: void ! 40: releasetmp() ! 41: { ! 42: if (tfp != NULL) ! 43: fclose(tfp); ! 44: unlink(tmpfile); ! 45: } ! 46: ! 47: /* ! 48: * Modes are: ! 49: * "w" to write a letter ! 50: * "r" to read a letter ! 51: * "ru" to read only undeleted letters ! 52: */ ! 53: letter * ! 54: lopen(n, mode) ! 55: int n; ! 56: char *mode; ! 57: { ! 58: letter *lp, *rv = NULL; ! 59: ! 60: if (n >= NLETTERS) ! 61: return NULL; ! 62: ! 63: lp = &let[n]; ! 64: if (strcmp(mode, "w")==0) { ! 65: lp->status = L_USED; ! 66: (void)fseek(tfp, 0L, 2); ! 67: lp->address = ftell(tfp); ! 68: lp->offset = lp->size = 0; ! 69: rv = lp; ! 70: ! 71: } else if (strcmp(mode, "r")==0) { ! 72: if (lp->status & L_USED) { ! 73: lp->offset = 0; ! 74: (void)fseek(tfp, lp->address, 0); ! 75: rv = lp; ! 76: } ! 77: ! 78: } else if (strcmp(mode, "ru")==0) { ! 79: if ((lp->status & L_USED) && !(lp->status & L_DELETED)) { ! 80: lp->offset = 0; ! 81: (void)fseek(tfp, lp->address, 0); ! 82: rv = lp; ! 83: } ! 84: } ! 85: ! 86: lastp = rv; ! 87: return rv; ! 88: } ! 89: ! 90: extern char * ! 91: lgets(bp, len, lp) ! 92: char *bp; ! 93: int len; ! 94: letter *lp; ! 95: { ! 96: char *rv; ! 97: ! 98: ASSERT(lp->status & L_USED, "tmpfile botch"); ! 99: if (lp != lastp) ! 100: (void)fseek(tfp, lp->address+lp->offset, 0); ! 101: if (lp->offset >= lp->size) ! 102: return NULL; ! 103: if (lp->offset+len > lp->size) ! 104: len = lp->size - lp->offset + 1; ! 105: rv = fgets(bp, len, tfp); ! 106: ASSERT(rv != NULL, "tmpfile botch"); ! 107: lp->offset = ftell(tfp) - lp->address; ! 108: lastp = lp; ! 109: return bp; ! 110: } ! 111: ! 112: extern void ! 113: lputs(bp, lp) ! 114: char *bp; ! 115: letter *lp; ! 116: { ! 117: int rv; ! 118: ! 119: ASSERT(lp->status & L_USED, "tmpfile botch"); ! 120: if (lp != lastp) ! 121: (void)fseek(tfp, lp->address+lp->offset, 0); ! 122: rv = fputs(bp, tfp); ! 123: ASSERT(rv != EOF, "can't write to /tmp"); ! 124: lp->size = lp->offset = ftell(tfp) - lp->address; ! 125: lastp = lp; ! 126: } ! 127: ! 128: extern void ! 129: lputc(c, lp) ! 130: char c; ! 131: letter *lp; ! 132: { ! 133: char rv; ! 134: ! 135: ASSERT(lp->status & L_USED, "tmpfile botch"); ! 136: if (lp != lastp) ! 137: (void)fseek(tfp, lp->address+lp->offset, 0); ! 138: rv = fputc(c, tfp); ! 139: ASSERT(rv != EOF, "can't write to /tmp"); ! 140: lp->size = lp->offset = ftell(tfp) - lp->address; ! 141: lastp = lp; ! 142: } ! 143: ! 144: extern long ! 145: ltell(lp) ! 146: letter *lp; ! 147: { ! 148: ASSERT(lp->status & L_USED, "tmpfile botch"); ! 149: return lp->offset; ! 150: } ! 151: ! 152: extern long ! 153: lsize(lp) ! 154: letter *lp; ! 155: { ! 156: ASSERT(lp->status & L_USED, "tmpfile botch"); ! 157: return lp->size; ! 158: } ! 159: ! 160: extern int ! 161: letseek(lp, off) ! 162: letter *lp; ! 163: long off; ! 164: { ! 165: ASSERT(lp->status & L_USED, "tmpfile botch"); ! 166: lp->offset = off < lp->size ? off : lp->size - 1; ! 167: lastp = NULL; ! 168: return 0; ! 169: } ! 170: ! 171: extern int ! 172: ldelete(n) ! 173: int n; ! 174: { ! 175: ASSERT(n>= 0 && n < NLETTERS && (let[n].status & L_USED), "tmpfile botch"); ! 176: let[n].status |= L_DELETED; ! 177: return 1; ! 178: } ! 179: ! 180: extern int ! 181: lundelete(n) ! 182: int n; ! 183: { ! 184: ASSERT(n>= 0 && n < NLETTERS && (let[n].status & L_USED), "tmpfile botch"); ! 185: let[n].status &= ~L_DELETED; ! 186: return 1; ! 187: } ! 188: ! 189: extern int ! 190: copyto(fp, lp, onatty, escape) ! 191: FILE *fp; ! 192: letter *lp; ! 193: int onatty; ! 194: int escape; ! 195: { ! 196: char buf[FROMLINESIZE]; ! 197: ! 198: while (fgets(buf, FROMLINESIZE, fp)!=NULL) { ! 199: if (onatty && buf[0]=='.' && buf[1]=='\n' && buf[2]=='\0') ! 200: break; ! 201: if (escape && strncmp(buf, FROM, FSIZE)==0) ! 202: lputc('>', lp); ! 203: (void)lputs(buf, lp); ! 204: } ! 205: } ! 206: ! 207: extern int ! 208: copyfrom(lp, fp) ! 209: letter *lp; ! 210: FILE *fp; ! 211: { ! 212: char buf[FROMLINESIZE]; ! 213: ! 214: while (lgets(buf, FROMLINESIZE, lp)!=NULL) ! 215: (void)fputs(buf, fp); ! 216: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.