📄 msgs.c
字号:
/*- * Copyright (c) 1980, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1980, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)msgs.c 8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * msgs - a user bulletin board program * * usage: * msgs [fhlopq] [[-]number] to read messages * msgs -s to place messages * msgs -c [-days] to clean up the bulletin board * * prompt commands are: * y print message * n flush message, go to next message * q flush message, quit * p print message, turn on 'pipe thru more' mode * P print message, turn off 'pipe thru more' mode * - reprint last message * s[-][<num>] [<filename>] save message * m[-][<num>] mail with message in temp mbox * x exit without flushing this message * <num> print message number <num> */#define V7 /* will look for TERM in the environment */#define OBJECT /* will object to messages without Subjects *//* #define REJECT /* will reject messages without Subjects (OBJECT must be defined also) *//* #define UNBUFFERED /* use unbuffered output */#include <sys/param.h>#include <sys/dir.h>#include <sys/stat.h>#include <ctype.h>#include <errno.h>#include <pwd.h>#include <setjmp.h>#include <sgtty.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include "pathnames.h"#define CMODE 0666 /* bounds file creation mode */#define NO 0#define YES 1#define SUPERUSER 0 /* superuser uid */#define DAEMON 1 /* daemon uid */#define NLINES 24 /* default number of lines/crt screen */#define NDAYS 21 /* default keep time for messages */#define DAYS *24*60*60 /* seconds/day */#define MSGSRC ".msgsrc" /* user's rc file */#define BOUNDS "bounds" /* message bounds file */#define NEXT "Next message? [yq]"#define MORE "More? [ynq]"#define NOMORE "(No more) [q] ?"typedef char bool;FILE *msgsrc;FILE *newmsg;char *sep = "-";char inbuf[BUFSIZ];char fname[128];char cmdbuf[128];char subj[128];char from[128];char date[128];char *ptr;char *in;bool local;bool ruptible;bool totty;bool seenfrom;bool seensubj;bool blankline;bool printing = NO;bool mailing = NO;bool quitit = NO;bool sending = NO;bool intrpflg = NO;int uid;int msg;int prevmsg;int lct;int nlines;int Lpp = 0;time_t t;time_t keep;struct sgttyb otty;char *mktemp();char *nxtfld();void onintr();void onsusp();/* option initialization */bool hdrs = NO;bool qopt = NO;bool hush = NO;bool send_msg = NO;bool locomode = NO;bool use_pager = NO;bool clean = NO;bool lastcmd = NO;jmp_buf tstpbuf;main(argc, argv)int argc; char *argv[];{ bool newrc, already; int rcfirst = 0; /* first message to print (from .rc) */ int rcback = 0; /* amount to back off of rcfirst */ int firstmsg, nextmsg, lastmsg = 0; int blast = 0; FILE *bounds;#ifdef UNBUFFERED setbuf(stdout, NULL);#endif gtty(fileno(stdout), &otty); time(&t); setuid(uid = getuid()); ruptible = (signal(SIGINT, SIG_IGN) == SIG_DFL); if (ruptible) signal(SIGINT, SIG_DFL); argc--, argv++; while (argc > 0) { if (isdigit(argv[0][0])) { /* starting message # */ rcfirst = atoi(argv[0]); } else if (isdigit(argv[0][1])) { /* backward offset */ rcback = atoi( &( argv[0][1] ) ); } else { ptr = *argv; while (*ptr) switch (*ptr++) { case '-': break; case 'c': if (uid != SUPERUSER && uid != DAEMON) { fprintf(stderr, "Sorry\n"); exit(1); } clean = YES; break; case 'f': /* silently */ hush = YES; break; case 'h': /* headers only */ hdrs = YES; break; case 'l': /* local msgs only */ locomode = YES; break; case 'o': /* option to save last message */ lastcmd = YES; break; case 'p': /* pipe thru 'more' during long msgs */ use_pager = YES; break; case 'q': /* query only */ qopt = YES; break; case 's': /* sending TO msgs */ send_msg = YES; break; default: fprintf(stderr, "usage: msgs [fhlopq] [[-]number]\n"); exit(1); } } argc--, argv++; } /* * determine current message bounds */ sprintf(fname, "%s/%s", _PATH_MSGS, BOUNDS); bounds = fopen(fname, "r"); if (bounds != NULL) { fscanf(bounds, "%d %d\n", &firstmsg, &lastmsg); fclose(bounds); blast = lastmsg; /* save upper bound */ } if (clean) keep = t - (rcback? rcback : NDAYS) DAYS; if (clean || bounds == NULL) { /* relocate message bounds */ struct direct *dp; struct stat stbuf; bool seenany = NO; DIR *dirp; dirp = opendir(_PATH_MSGS); if (dirp == NULL) { perror(_PATH_MSGS); exit(errno); } firstmsg = 32767; lastmsg = 0; for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)){ register char *cp = dp->d_name; register int i = 0; if (dp->d_ino == 0) continue; if (dp->d_namlen == 0) continue; if (clean) sprintf(inbuf, "%s/%s", _PATH_MSGS, cp); while (isdigit(*cp)) i = i * 10 + *cp++ - '0'; if (*cp) continue; /* not a message! */ if (clean) { if (stat(inbuf, &stbuf) != 0) continue; if (stbuf.st_mtime < keep && stbuf.st_mode&S_IWRITE) { unlink(inbuf); continue; } } if (i > lastmsg) lastmsg = i; if (i < firstmsg) firstmsg = i; seenany = YES; } closedir(dirp); if (!seenany) { if (blast != 0) /* never lower the upper bound! */ lastmsg = blast; firstmsg = lastmsg + 1; } else if (blast > lastmsg) lastmsg = blast; if (!send_msg) { bounds = fopen(fname, "w"); if (bounds == NULL) { perror(fname); exit(errno); } chmod(fname, CMODE); fprintf(bounds, "%d %d\n", firstmsg, lastmsg); fclose(bounds); } } if (send_msg) { /* * Send mode - place msgs in _PATH_MSGS */ bounds = fopen(fname, "w"); if (bounds == NULL) { perror(fname); exit(errno); } nextmsg = lastmsg + 1; sprintf(fname, "%s/%d", _PATH_MSGS, nextmsg); newmsg = fopen(fname, "w"); if (newmsg == NULL) { perror(fname); exit(errno); } chmod(fname, 0644); fprintf(bounds, "%d %d\n", firstmsg, nextmsg); fclose(bounds); sending = YES; if (ruptible) signal(SIGINT, onintr); if (isatty(fileno(stdin))) { ptr = getpwuid(uid)->pw_name; printf("Message %d:\nFrom %s %sSubject: ", nextmsg, ptr, ctime(&t)); fflush(stdout); fgets(inbuf, sizeof inbuf, stdin); putchar('\n'); fflush(stdout); fprintf(newmsg, "From %s %sSubject: %s\n", ptr, ctime(&t), inbuf); blankline = seensubj = YES; } else blankline = seensubj = NO; for (;;) { fgets(inbuf, sizeof inbuf, stdin); if (feof(stdin) || ferror(stdin)) break; blankline = (blankline || (inbuf[0] == '\n')); seensubj = (seensubj || (!blankline && (strncmp(inbuf, "Subj", 4) == 0))); fputs(inbuf, newmsg); }#ifdef OBJECT if (!seensubj) { printf("NOTICE: Messages should have a Subject field!\n");#ifdef REJECT unlink(fname);#endif exit(1); }#endif exit(ferror(stdin)); } if (clean) exit(0); /* * prepare to display messages */ totty = (isatty(fileno(stdout)) != 0); use_pager = use_pager && totty; sprintf(fname, "%s/%s", getenv("HOME"), MSGSRC); msgsrc = fopen(fname, "r"); if (msgsrc) { newrc = NO; fscanf(msgsrc, "%d\n", &nextmsg); fclose(msgsrc); if (nextmsg > lastmsg+1) { printf("Warning: bounds have been reset (%d, %d)\n", firstmsg, lastmsg); truncate(fname, (off_t)0); newrc = YES; } else if (!rcfirst) rcfirst = nextmsg - rcback; } else newrc = YES; msgsrc = fopen(fname, "r+"); if (msgsrc == NULL) msgsrc = fopen(fname, "w"); if (msgsrc == NULL) { perror(fname); exit(errno); } if (rcfirst) { if (rcfirst > lastmsg+1) { printf("Warning: the last message is number %d.\n", lastmsg); rcfirst = nextmsg; } if (rcfirst > firstmsg) firstmsg = rcfirst; /* don't set below first msg */ } if (newrc) { nextmsg = firstmsg; fseek(msgsrc, 0L, 0); fprintf(msgsrc, "%d\n", nextmsg); fflush(msgsrc); }#ifdef V7 if (totty) { struct winsize win; if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1) Lpp = win.ws_row; if (Lpp <= 0) { if (tgetent(inbuf, getenv("TERM")) <= 0 || (Lpp = tgetnum("li")) <= 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -