-
-
-/*
-** This function is performed implicitly by getbbent.c:
-** bb->bb_map = map_name(bb->bb_file);
-*/
-
-char *
-map_name(char *file)
-{
- register char *cp, *dp;
- static char buffer[BUFSIZ];
-
- if ((dp = strchr(cp = mhbasename(file), '.')) == NULL)
- dp = cp + strlen(cp);
- if (cp == file)
- snprintf(buffer, sizeof(buffer), ".%.*s%s",
- (int)(dp - cp), cp, ".map");
- else
- snprintf (buffer, sizeof(buffer), "%.*s.%.*s%s",
- (int)(cp - file), file, (int)(dp - cp),
- cp, ".map");
-
- return buffer;
-}
-
-
-int
-map_read(char *file, long pos, struct drop **drops, int noisy)
-{
- register int i, md, msgp;
- register char *cp;
- struct drop d;
- register struct drop *mp, *dp;
-
- if ((md = open(cp = map_name(file), O_RDONLY)) == NOTOK
- || map_chk(cp, md, mp = &d, pos, noisy)) {
- if (md != NOTOK)
- close(md);
- return 0;
- }
-
- msgp = mp->d_id;
- dp = (struct drop *) calloc((size_t) (msgp + 1), sizeof(*dp));
- if (dp == NULL) {
- close(md);
- return 0;
- }
-
- memcpy((char *) dp, (char *) mp, sizeof(*dp));
-
- lseek(md, (off_t) sizeof(*mp), SEEK_SET);
- if ((i = read(md, (char *) (dp + 1), msgp * sizeof(*dp))) <
- sizeof(*dp)) {
- i = 0;
- free((char *) dp);
- } else {
-#ifdef NTOHLSWAP
- register struct drop *tdp;
- int j;
-
- 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);
- }
-#endif
- *drops = dp;
- }
-
- close(md);
-
- return (i / sizeof(*dp));
-}
-
-
-int
-map_write(char *mailbox, int md, int id, long last, off_t start,
- off_t stop, long pos, int size, int noisy)
-{
- register int i;
- int clear, fd, td;
- char *file;
- register struct drop *dp;
- struct drop d1, d2, *rp;
- register FILE *fp;
- struct stat st;
-
- if ((fd = map_open(file = map_name(mailbox), md)) == NOTOK)
- return NOTOK;
-
- if ((fstat(fd, &st) == OK) && (st.st_size > 0))
- clear = 0;
- else
- clear = 1;
-
- if (!clear && map_chk(file, fd, &d1, pos, noisy)) {
- unlink(file);
- mbx_close(file, fd);
- if ((fd = map_open(file, 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)
- close(td);
- mbx_close(file, fd);
- return NOTOK;
- }
-
- switch (i = mbx_read(fp, 0, &rp, noisy)) {
- case NOTOK:
- fclose(fp);
- mbx_close(file, fd);
- return NOTOK;
-
- case OK:
- fclose(fp);
- break;
-
- default:
- d1.d_id = 0;
- for (dp = rp; i-- >0; dp++) {
- if (dp->d_start == start)
- dp->d_id = id;
- lseek(fd, (off_t) (++d1.d_id * sizeof(*dp)),
- SEEK_SET);
- if (write(fd, (char *)dp, sizeof(*dp)) != sizeof(*dp)) {
- if (noisy)
- admonish(file, "write error");
- mbx_close(file, fd);
- fclose(fp);
- return NOTOK;
- }
- }
- free((char *) rp);
- fclose(fp);
- break;
- }
- } else {
- if (last == 0)
- last = d1.d_start;
- dp = &d2;
- dp->d_id = id;
- dp->d_size = (long) (size ? size : mbx_size(fd, start, stop));
- dp->d_start = start;
- dp->d_stop = stop;
- lseek(fd, (off_t) (++d1.d_id * sizeof(*dp)), SEEK_SET);
- if (write(fd, (char *) dp, sizeof(*dp)) != sizeof(*dp)) {
- if (noisy)
- admonish(file, "write error");
- mbx_close(file, fd);
- return NOTOK;
- }
- }
-
- dp = &d1;
- dp->d_size = DRVRSN;
- dp->d_start = (long) last;
- dp->d_stop = lseek(md, (off_t) 0, SEEK_CUR);
-
- lseek(fd, (off_t) 0, SEEK_SET);
- if (write(fd, (char *) dp, sizeof(*dp)) != sizeof(*dp)) {
- if (noisy)
- admonish(file, "write error");
- mbx_close(file, fd);
- return NOTOK;
- }
-
- mbx_close(file, fd);
-
- return OK;
-}
-
-
-static int
-map_open(char *file, int md)
-{
- mode_t mode;
- struct stat st;
-
- mode = fstat(md, &st) != NOTOK ?
- (mode_t) (st.st_mode & 0777) : m_gmprot();
- return mbx_open(file, OTHER_FORMAT, st.st_uid, st.st_gid, mode);
-}
-
-
-int
-map_chk(char *file, int fd, struct drop *dp, long pos, int noisy)
-{
- long count;
- struct drop d, tmpd;
- register struct drop *dl;
-
- if (read(fd, (char *) &tmpd, sizeof(*dp)) != sizeof(*dp)) {
-#ifdef notdef
- admonish(NULL, "%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(NULL, "%s: version mismatch (%d != %d)",
- file, dp->d_size, DRVRSN);
- return NOTOK;
- }
-
- if (dp->d_stop != pos) {
- if (noisy && pos != (long) 0)
- admonish(NULL, "%s: pointer mismatch or incomplete index (%ld!=%ld)", file, dp->d_stop, (long) pos);
- return NOTOK;
- }
-
- if ((long) ((dp->d_id + 1) * sizeof(*dp)) != (long) lseek(fd, (off_t) 0, SEEK_END)) {
- if (noisy)
- admonish(NULL, "%s: corrupt index(1)", file);
- return NOTOK;
- }
-
- dl = &d;
- count = (long) strlen(mmdlm2);
- lseek(fd, (off_t) (dp->d_id * sizeof(*dp)), SEEK_SET);
- 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(NULL, "%s: corrupt index(2)", file);
- return NOTOK;
- }
-
- return OK;
-}