|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 14455 (0x3877)
Types: TextFile
Names: »dropsbr.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦3658e588a⟧ »EurOpenD3/mail/mh/mh-6.7.tar.Z«
└─⟦c75e36ecb⟧
└─⟦this⟧ »mh-6.7/uip/dropsbr.c«
/* dropsbr.c - write to a mailbox */
#ifndef lint
static char ident[] = "@(#)$Id: dropsbr.c,v 1.11 90/04/05 15:01:09 sources Exp $";
#endif lint
#include <stdio.h>
#ifndef MMDFONLY
#include "../h/mh.h"
#include "../h/dropsbr.h"
#include "../zotnet/mts.h"
#else MMDFONLY
#include "dropsbr.h"
#include "strings.h"
#include "mmdfonly.h"
#endif MMDFONLY
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#if (defined(BSD42) || defined(SOCKETS)) && defined(NTOHLSWAP)
#include <netinet/in.h>
#else
#define ntohl(n) (n)
#endif
#define MMDF 1
#define UUCP 2
/* \f
*/
static int mbx_style = MMDF;
static int mbx_create(), mbx_chk(), map_open();
extern int errno;
long lseek ();
/* \f
*/
int mbx_mmdf () {
int style = mbx_style;
mbx_style = MMDF;
return style;
}
int mbx_uucp () {
int style = mbx_style;
mbx_style = UUCP;
return style;
}
/* \f
*/
int mbx_open (file, uid, gid, mode)
char *file;
int uid,
gid,
mode;
{
int clear,
fd;
if ((fd = mbx_Xopen (file, uid, gid, mode, &clear)) == NOTOK)
return fd;
if (!clear)
switch (mbx_style) {
case MMDF:
default:
if (mbx_chk (fd) == NOTOK) {
(void) close (fd);
return NOTOK;
}
break;
case UUCP:
if (lseek (fd, 0L, 2) == (long) NOTOK) {
(void) close (fd);
return NOTOK;
}
break;
}
return fd;
}
/* \f
*/
int mbx_Xopen (file, uid, gid, mode, clear)
char *file;
int uid,
gid,
mode,
*clear;
{
register int j;
int count,
fd;
struct stat st;
for (*clear = 0, count = 4, j = 0; count > 0; count--)
if ((fd = lkopen (file, 6)) == NOTOK)
switch (errno) {
case ENOENT:
if (mbx_create (file, uid, gid, mode) == NOTOK)
return NOTOK;
(*clear)++;
break;
#ifdef BSD42
case EWOULDBLOCK:
#endif BSD42
case ETXTBSY:
j = errno;
sleep (5);
break;
default:
return NOTOK;
}
else {
*clear = fstat (fd, &st) != NOTOK && st.st_size == 0L;
break;
}
errno = j;
return fd;
}
/* \f
*/
static int mbx_create (file, uid, gid, mode)
char *file;
int uid,
gid,
mode;
{
int fd;
if ((fd = creat (file, 0600)) == NOTOK)
return NOTOK;
(void) close (fd);
(void) chown (file, uid, gid);
(void) chmod (file, mode);
return OK;
}
static int mbx_chk (fd)
int fd;
{
int count;
char ldelim[BUFSIZ];
count = strlen (mmdlm2);
if (lseek (fd, (long) (-count), 2) == (long) NOTOK
|| read (fd, ldelim, count) != count)
return NOTOK;
ldelim[count] = NULL;
if (strcmp (ldelim, mmdlm2)
&& write (fd, "\n", 1) != 1
&& write (fd, mmdlm2, count) != count)
return NOTOK;
return OK;
}
/* \f
*/
int mbx_read (fp, pos, drops, noisy)
register FILE *fp;
register long pos;
struct drop **drops;
int noisy;
{
register int len,
size;
long ld1,
ld2;
register char *bp;
char buffer[BUFSIZ];
register struct drop *cp,
*dp,
*ep,
*pp;
pp = (struct drop *) calloc ((unsigned) (len = MAXFOLDER), sizeof *dp);
if (pp == NULL) {
if (noisy)
admonish (NULLCP, "unable to allocate drop storage");
return NOTOK;
}
ld1 = (long) strlen (mmdlm1);
ld2 = (long) strlen (mmdlm2);
(void) fseek (fp, pos, 0);
for (ep = (dp = pp) + len - 1; fgets (buffer, sizeof buffer, fp);) {
size = 0;
if (strcmp (buffer, mmdlm1) == 0)
pos += ld1, dp -> d_start = pos;
else {
dp -> d_start = pos, pos += (long) strlen (buffer);
for (bp = buffer; *bp; bp++, size++)
if (*bp == '\n')
size++;
}
while (fgets (buffer, sizeof buffer, fp) != NULL)
if (strcmp (buffer, mmdlm2) == 0)
break;
else {
pos += (long) strlen (buffer);
for (bp = buffer; *bp; bp++, size++)
if (*bp == '\n')
size++;
}
if (dp -> d_start != pos) {
dp -> d_id = 0;
dp -> d_size = size;
dp -> d_stop = pos;
dp++;
}
pos += ld2;
if (dp >= ep) {
register int curlen = dp - pp;
cp = (struct drop *) realloc ((char *) pp,
(unsigned) (len += MAXFOLDER) * sizeof *pp);
if (cp == NULL) {
if (noisy)
admonish (NULLCP, "unable to allocate drop storage");
free ((char *) pp);
return 0;
}
dp = cp + curlen, ep = (pp = cp) + len - 1;
}
}
if (dp == pp)
free ((char *) pp);
else
*drops = pp;
return (dp - pp);
}
/* \f
*/
int mbx_write (mailbox, md, fp, id, last, pos, stop, mapping, noisy)
char *mailbox;
register FILE *fp;
int md,
id,
mapping,
noisy;
long last;
register long pos,
stop;
{
register int i,
j,
size;
register long start,
off;
register char *cp;
char buffer[BUFSIZ];
off = lseek (md, 0L, 1);
j = strlen (mmdlm1);
if (write (md, mmdlm1, j) != j)
return NOTOK;
start = lseek (md, 0L, 1);
size = 0;
(void) fseek (fp, pos, 0);
while (fgets (buffer, sizeof buffer, fp) != NULL && pos < stop) {
i = strlen (buffer);
for (j = 0; (j = stringdex (mmdlm1, buffer)) >= 0; buffer[j]++)
continue;
for (j = 0; (j = stringdex (mmdlm2, buffer)) >= 0; buffer[j]++)
continue;
if (write (md, buffer, i) != i)
return NOTOK;
pos += (long) i;
if (mapping)
for (cp = buffer; i-- > 0; size++)
if (*cp++ == '\n')
size++;
}
stop = lseek (md, 0L, 1);
j = strlen (mmdlm2);
if (write (md, mmdlm2, j) != j)
return NOTOK;
if (mapping)
(void) map_write (mailbox, md, id, last, start, stop, off, size, noisy);
return OK;
}
/* \f
*/
int mbx_copy (mailbox, md, fd, mapping, text, noisy)
char *mailbox;
int md,
fd,
mapping,
noisy;
char *text;
{
register int i,
j,
size;
register long start,
stop,
pos;
register char *cp;
char buffer[BUFSIZ];
register FILE *fp;
pos = lseek (md, 0L, 1);
size = 0;
switch (mbx_style) {
case MMDF:
default:
j = strlen (mmdlm1);
if (write (md, mmdlm1, j) != j)
return NOTOK;
start = lseek (md, 0L, 1);
if (text) {
i = strlen (text);
if (write (md, text, i) != i)
return NOTOK;
for (cp = text; *cp++; size++)
if (*cp == '\n')
size++;
}
while ((i = read (fd, buffer, sizeof buffer)) > 0) {
for (j = 0;
(j = stringdex (mmdlm1, buffer)) >= 0;
buffer[j]++)
continue;
for (j = 0;
(j = stringdex (mmdlm2, buffer)) >= 0;
buffer[j]++)
continue;
if (write (md, buffer, i) != i)
return NOTOK;
if (mapping)
for (cp = buffer; i-- > 0; size++)
if (*cp++ == '\n')
size++;
}
stop = lseek (md, 0L, 1);
j = strlen (mmdlm2);
if (write (md, mmdlm2, j) != j)
return NOTOK;
if (mapping)
(void) map_write (mailbox, md, 0, 0L, start, stop, pos, size,
noisy);
return (i != NOTOK ? OK : NOTOK);
case UUCP: /* I hate this... */
if ((j = dup (fd)) == NOTOK)
return NOTOK;
if ((fp = fdopen (j, "r")) == NULL) {
(void) close (j);
return NOTOK;
}
start = lseek (md, 0L, 1);
if (text) {
i = strlen (text);
if (write (md, text, i) != i)
return NOTOK;
for (cp = text; *cp++; size++)
if (*cp == '\n')
size++;
}
for (j = 0; fgets (buffer, sizeof buffer, fp) != NULL; j++) {
if (j != 0 && strncmp (buffer, "From ", 5) == 0) {
(void) write (fd, ">", 1);
size++;
}
i = strlen (buffer);
if (write (md, buffer, i) != i) {
(void) fclose (fp);
return NOTOK;
}
if (mapping)
for (cp = buffer; i-- > 0; size++)
if (*cp++ == '\n')
size++;
}
(void) fclose (fp);
(void) lseek (fd, 0L, 2);
stop = lseek (md, 0L, 1);
if (mapping)
(void) map_write (mailbox, md, 0, 0L, start, stop, pos, size,
noisy);
return OK;
}
}
/* \f
*/
int mbx_size (md, start, stop)
int md;
long start,
stop;
{
register int i,
fd;
register long pos;
register FILE *fp;
if ((fd = dup (md)) == NOTOK || (fp = fdopen (fd, "r")) == NULL) {
if (fd != NOTOK)
(void) close (fd);
return NOTOK;
}
(void) fseek (fp, start, 0);
for (i = 0, pos = stop - start; pos-- > 0; i++)
if (fgetc (fp) == '\n')
i++;
(void) fclose (fp);
return i;
}
/* \f
*/
int mbx_close (mailbox, md)
char *mailbox;
int md;
{
(void) lkclose (md, mailbox);
return OK;
}
/* \f
*/
/* This function is performed implicitly by getbbent.c:
bb -> bb_map = map_name (bb -> bb_file);
*/
char *map_name (file)
register char *file;
{
register char *cp,
*dp;
static char buffer[BUFSIZ];
if ((dp = index (cp = r1bindex (file, '/'), '.')) == NULL)
dp = cp + strlen (cp);
if (cp == file)
(void) sprintf (buffer, ".%.*s%s", dp - cp, cp, ".map");
else
(void) sprintf (buffer, "%.*s.%.*s%s", cp - file, file, dp - cp,
cp, ".map");
return buffer;
}
/* \f
*/
int map_read (file, pos, drops, noisy)
char *file;
long pos;
struct drop **drops;
int noisy;
{
register int i, j,
md,
msgp;
register char *cp;
struct drop d;
register struct drop *mp,
*dp;
if ((md = open (cp = map_name (file), 0)) == NOTOK
|| map_chk (cp, md, mp = &d, pos, noisy)) {
if (md != NOTOK)
(void) close (md);
return 0;
}
msgp = mp -> d_id;
dp = (struct drop *) calloc ((unsigned) (msgp + 1), sizeof *dp);
if (dp == NULL) {
(void) close (md);
return 0;
}
bcopy ((char *) mp, (char *) dp, sizeof *dp);
(void) lseek (md, (long) sizeof *mp, 0);
if ((i = read (md, (char *) (dp + 1), msgp * sizeof *dp)) < sizeof *dp) {
i = 0;
free ((char *) dp);
}
else {
#ifdef NTOHLSWAP
register struct drop *tdp;
for (j = 0, tdp = dp; j < i / sizeof(*dp); j++, tdp++) {
tdp->d_id = ntohl(tdp->d_id);
tdp->d_size = ntohl(tdp->d_size);
tdp->d_start = ntohl(tdp->d_start);
tdp->d_stop = ntohl(tdp->d_stop);
tdp++;
}
#endif
*drops = dp;
}
(void) close (md);
return (i / sizeof *dp);
}
/* \f
*/
int map_write (mailbox, md, id, last, start, stop, pos, size, noisy)
register char *mailbox;
int md,
id,
size,
noisy;
long last,
start,
stop,
pos;
{
register int i;
int clear,
fd,
td;
char *file;
register struct drop *dp;
struct drop d1,
d2,
*rp;
register FILE *fp;
if ((fd = map_open (file = map_name (mailbox), &clear, md)) == NOTOK)
return NOTOK;
if (!clear && map_chk (file, fd, &d1, pos, noisy)) {
(void) unlink (file);
(void) mbx_close (file, fd);
if ((fd = map_open (file, &clear, md)) == NOTOK)
return NOTOK;
clear++;
}
if (clear) {
if ((td = dup (md)) == NOTOK || (fp = fdopen (td, "r")) == NULL) {
if (noisy)
admonish (file, "unable to %s", td != NOTOK ? "fdopen" : "dup");
if (td != NOTOK)
(void) close (td);
(void) mbx_close (file, fd);
return NOTOK;
}
switch (i = mbx_read (fp, 0L, &rp, noisy)) {
case NOTOK:
(void) fclose (fp);
(void) mbx_close (file, fd);
return NOTOK;
case OK:
break;
default:
d1.d_id = 0;
for (dp = rp; i-- >0; dp++) {
if (dp -> d_start == start)
dp -> d_id = id;
(void) lseek (fd, (long) (++d1.d_id * sizeof *dp), 0);
if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
if (noisy)
admonish (file, "write error");
(void) mbx_close (file, fd);
(void) fclose (fp);
return NOTOK;
}
}
free ((char *) rp);
break;
}
}
else {
if (last == 0)
last = d1.d_start;
dp = &d2;
dp -> d_id = id;
dp -> d_size = size ? size : mbx_size (fd, start, stop);
dp -> d_start = start;
dp -> d_stop = stop;
(void) lseek (fd, (long) (++d1.d_id * sizeof *dp), 0);
if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
if (noisy)
admonish (file, "write error");
(void) mbx_close (file, fd);
return NOTOK;
}
}
dp = &d1;
dp -> d_size = DRVRSN;
dp -> d_start = last;
dp -> d_stop = lseek (md, 0L, 1);
(void) lseek (fd, 0L, 0);
if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
if (noisy)
admonish (file, "write error");
(void) mbx_close (file, fd);
return NOTOK;
}
(void) mbx_close (file, fd);
return OK;
}
/* \f
*/
static int map_open (file, clear, md)
char *file;
int *clear,
md;
{
int mode;
struct stat st;
mode = fstat (md, &st) != NOTOK ? (int) (st.st_mode & 0777) : m_gmprot ();
return mbx_Xopen (file, st.st_uid, st.st_gid, mode, clear);
}
/* \f
*/
int map_chk (file, fd, dp, pos, noisy)
char *file;
int fd,
noisy;
register struct drop *dp;
long pos;
{
long count;
struct drop d, tmpd;
register struct drop *dl;
if (read (fd, (char *) &tmpd, sizeof *dp) != sizeof *dp) {
#ifdef notdef
admonish (NULLCP, "%s: missing or partial index", file);
#endif notdef
return NOTOK;
}
#ifndef NTOHLSWAP
*dp = tmpd; /* if ntohl(n)=(n), can use struct assign */
#else
dp->d_id = ntohl(tmpd.d_id);
dp->d_size = ntohl(tmpd.d_size);
dp->d_start = ntohl(tmpd.d_start);
dp->d_stop = ntohl(tmpd.d_stop);
#endif
if (dp -> d_size != DRVRSN) {
if (noisy)
admonish (NULLCP, "%s: version mismatch (%d != %d)", file,
dp->d_size, DRVRSN);
return NOTOK;
}
if (dp -> d_stop != pos) {
if (noisy && pos != 0L)
admonish (NULLCP,
"%s: pointer mismatch or incomplete index (%ld!=%ld)",
file, dp -> d_stop, pos);
return NOTOK;
}
if ((long) ((dp -> d_id + 1) * sizeof *dp) != lseek (fd, 0L, 2)) {
if (noisy)
admonish (NULLCP, "%s: corrupt index(1)", file);
return NOTOK;
}
dl = &d;
count = (long) strlen (mmdlm2);
(void) lseek (fd, (long) (dp -> d_id * sizeof *dp), 0);
if (read (fd, (char *) dl, sizeof *dl) != sizeof *dl
|| (ntohl(dl -> d_stop) != dp -> d_stop
&& ntohl(dl -> d_stop) + count != dp -> d_stop)) {
if (noisy)
admonish (NULLCP, "%s: corrupt index(2)", file);
return NOTOK;
}
return OK;
}