/********************************************************************** * edit room description * Ask user if they want to edit <R>oom aide only, <D>escription only, * <B>oth, or <Q>uit. * Contingent on option chosen, edit the item(s). When done, write * the description to the descfile. * raname is taken either from reading the description or set anew. * If a new aide is chosen, read his/her user file and assign ->usernum * to be roomaide. **********************************************************************/ void editdesc(void) { char choice = '0'; char descfile[100]; char newdescfile[100]; int dfd; /* desc file descriptor */ int dummy; /* readmsg() needs this: returns YES/NO */ int err; /* makemessage returns this */ char raname[MAXALIAS+1]; int upload; char *cp; struct mheader *mh; int size; unsigned char *infop; struct user *tmpuser; sprintf(descfile, "%sroom%d", DESCDIR, curr); sprintf(newdescfile, "%sroom%d.NEW", DESCDIR, curr); size = 0; if (!(infop = (unsigned char *)mymmap(descfile, &size, 0)) || !size) { colorize("@RDescription doesn't yet exist@G\n"); choice = 'B'; } else { readmessage(infop, &dummy, raname, FALSE, 0); munmap((void *)infop, size); } /* if it's a new description, don't bother prompting for choice */ if (choice != 'B') { printf("\nEdit <F>orum moderator only, <D>escription only, <B>oth, <Q>uit -> "); choice = get_single_quiet("FDBQ \n"); putchar('\n'); } if (choice == 'Q' || choice == ' ' || choice == '\n') return; if (choice == 'B' || choice == 'F') { cp = get_name("\nNew forum moderator -> ", 2); if (!*cp) return; if (!strcmp(cp, "Sysop")) msg->room[curr].roomaide = 0; else if (!(tmpuser = getuser(cp)) || tmpuser->f_invisible) { if (tmpuser) freeuser(tmpuser); printf("\nThere is no user %s on this BBS.\n", cp); return; } else { msg->room[curr].roomaide = tmpuser->usernum; freeuser(tmpuser); } if (choice == 'F') return; } printf("\nHit Y to upload a description or N to enter it normally (Y/N) -> "); if ((upload = yesno(-1))) printf("\n(Use control-D to end!)\n"); printf("\nEnter a new forum description...\n\n"); err = makemessage(NULL, MES_DESC, upload); if (err == ABORT) colorize("@RDescription not entered\n@G"); else if (err != SAVE) colorize("@RSome mystical error - can't make description\n@G"); else if ((dfd = open(newdescfile, O_WRONLY | O_CREAT | O_EXCL, 0640)) < 0) printf("error opening desc file to make final copy\n"); else { mh = (struct mheader *)(void *)tmpstart; write(dfd, tmpstart, mh->hlen + mh->len + 1); close(dfd); rename(newdescfile, descfile); } munmap((void *)tmpstart, 53248); if (err == SAVE) { printf("\nMark forum info as having been updated? (Y/N) -> "); if (yesno(-1)) msg->room[curr].descupdate = msg->room[curr].highest; } }
/* * Set up the input pointers while copying the mail file into /tmp. */ void setptr(FILE *ibuf, off_t offset) { int c, count; char *cp, *cp2; struct message this; FILE *mestmp; int maybe, inhead; char linebuf[LINESIZE], pathbuf[PATHSIZE]; int omsgCount; /* Get temporary file. */ (void)snprintf(pathbuf, sizeof(pathbuf), "%s/mail.XXXXXXXXXX", tmpdir); if ((c = mkstemp(pathbuf)) == -1 || (mestmp = Fdopen(c, "r+")) == NULL) err(1, "can't open %s", pathbuf); (void)rm(pathbuf); if (offset == 0) { msgCount = 0; } else { /* Seek into the file to get to the new messages */ (void)fseeko(ibuf, offset, SEEK_SET); /* * We need to make "offset" a pointer to the end of * the temp file that has the copy of the mail file. * If any messages have been edited, this will be * different from the offset into the mail file. */ (void)fseeko(otf, (off_t)0, SEEK_END); offset = ftello(otf); } omsgCount = msgCount; maybe = 1; inhead = 0; this.m_flag = MUSED|MNEW; this.m_size = 0; this.m_lines = 0; this.m_block = 0; this.m_offset = 0; for (;;) { if (fgets(linebuf, sizeof(linebuf), ibuf) == NULL) { if (append(&this, mestmp)) errx(1, "temporary file"); makemessage(mestmp, omsgCount); return; } count = strlen(linebuf); /* * Transforms lines ending in <CR><LF> to just <LF>. * This allows mail to be able to read Eudora mailboxes. */ if (count >= 2 && linebuf[count - 1] == '\n' && linebuf[count - 2] == '\r') { count--; linebuf[count - 1] = '\n'; } (void)fwrite(linebuf, sizeof(*linebuf), count, otf); if (ferror(otf)) errx(1, "/tmp"); if (count) linebuf[count - 1] = '\0'; if (maybe && linebuf[0] == 'F' && ishead(linebuf)) { msgCount++; if (append(&this, mestmp)) errx(1, "temporary file"); this.m_flag = MUSED|MNEW; this.m_size = 0; this.m_lines = 0; this.m_block = blockof(offset); this.m_offset = boffsetof(offset); inhead = 1; } else if (linebuf[0] == 0) { inhead = 0; } else if (inhead) { for (cp = linebuf, cp2 = "status";; cp++) { if ((c = *cp2++) == '\0') { while (isspace((unsigned char)*cp++)) ; if (cp[-1] != ':') break; while ((c = *cp++) != '\0') if (c == 'R') this.m_flag |= MREAD; else if (c == 'O') this.m_flag &= ~MNEW; inhead = 0; break; } if (*cp != c && *cp != toupper((unsigned char)c)) break; } } offset += count; this.m_size += count; this.m_lines++; maybe = linebuf[0] == 0; } }
/* * Set up the input pointers while copying the mail file into /tmp. */ PUBLIC void setptr(FILE *ibuf, off_t offset) { int c; size_t len; char *cp; const char *cp2; struct message this; FILE *mestmp; int maybe, inhead; char linebuf[LINESIZE]; int omsgCount; #ifdef THREAD_SUPPORT int nmsgCount; #else # define nmsgCount msgCount #endif /* Get temporary file. */ (void)snprintf(linebuf, LINESIZE, "%s/mail.XXXXXX", tmpdir); if ((c = mkstemp(linebuf)) == -1 || (mestmp = Fdopen(c, "re+")) == NULL) { (void)fprintf(stderr, "mail: can't open %s\n", linebuf); exit(1); } (void)unlink(linebuf); nmsgCount = get_abs_msgCount(); if (offset == 0) { nmsgCount = 0; } else { /* Seek into the file to get to the new messages */ (void)fseeko(ibuf, offset, 0); /* * We need to make "offset" a pointer to the end of * the temp file that has the copy of the mail file. * If any messages have been edited, this will be * different from the offset into the mail file. */ (void)fseek(otf, 0L, SEEK_END); offset = ftell(otf); } omsgCount = nmsgCount; maybe = 1; inhead = 0; message_init(&this, (off_t)0, MUSED|MNEW); for (;;) { if (fgets(linebuf, LINESIZE, ibuf) == NULL) { if (append(&this, mestmp)) err(EXIT_FAILURE, "temporary file"); makemessage(mestmp, omsgCount, nmsgCount); return; } len = strlen(linebuf); /* * Transforms lines ending in <CR><LF> to just <LF>. * This allows mail to be able to read Eudora mailboxes * that reside on a DOS partition. */ if (len >= 2 && linebuf[len - 1] == '\n' && linebuf[len - 2] == '\r') { linebuf[len - 2] = '\n'; len--; } (void)fwrite(linebuf, sizeof(*linebuf), len, otf); if (ferror(otf)) err(EXIT_FAILURE, "/tmp"); if (len) linebuf[len - 1] = 0; if (maybe && linebuf[0] == 'F' && ishead(linebuf)) { nmsgCount++; if (append(&this, mestmp)) err(EXIT_FAILURE, "temporary file"); message_init(&this, offset, MUSED|MNEW); inhead = 1; } else if (linebuf[0] == 0) { inhead = 0; } else if (inhead) { for (cp = linebuf, cp2 = "status";; cp++) { if ((c = *cp2++) == 0) { while (isspace((unsigned char)*cp++)) continue; if (cp[-1] != ':') break; while ((c = *cp++) != '\0') if (c == 'R') this.m_flag |= MREAD; else if (c == 'O') this.m_flag &= ~MNEW; inhead = 0; break; } if (*cp != c && *cp != toupper(c)) break; } } offset += len; this.m_size += len; this.m_lines++; if (!inhead) { int lines_plus_wraps = 1; int linelen = (int)strlen(linebuf); if (screenwidth && (int)linelen > screenwidth) { lines_plus_wraps = linelen / screenwidth; if (linelen % screenwidth != 0) ++lines_plus_wraps; } this.m_blines += lines_plus_wraps; } maybe = linebuf[0] == 0; } }