📄 bmutil.c
字号:
char buf[LINELEN], *cp;
FILE *fp;
if((fp = fopen(Arealist,READ_TEXT)) == NULL)
return 0;
while(fgets(buf,sizeof(buf),fp) != NULL) {
/* The first word on each line is all that matters */
if((cp = strchr(buf,' ')) == NULL)
if((cp = strchr(buf,'\t')) == NULL)
continue;
*cp = '\0';
if((cp = strchr(buf,'\t')) != NULL)
*cp = '\0';
if(stricmp(name,buf) == 0) { /* found it */
fclose(fp);
return 1;
}
}
fclose(fp);
return 0;
}
static int
lockit(m)
struct mbx *m;
{
int c, cnt = 0;
while(mlock(Mailspool,m->area)) {
ppause(1000L/MSPTICK); /* Wait one second */
if(++cnt == 10) {
cnt = 0;
c = tkeywait("Mail file is busy, Abort or Retry ? ",1);
if (c == 'A' || c == 'a' || c == EOF) {
mfclose(m);
return 1;
}
}
}
return 0;
}
/* read the next message or the current one if new */
int
doreadnext(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct mbx *m;
char buf[10], *newargv[2];
m = (struct mbx *) p;
if (m->mfile == NULL)
return 0;
if ((m->mbox[m->current].status & BM_READ) != 0) {
if (m->current == 1 && m->anyread == 0)
;
else if (m->current < m->nmsgs) {
m->current++;
} else {
printf("Last message\n");
return 0;
}
}
sprintf(buf,"%d",m->current);
newargv[0] = "read";
newargv[1] = buf;
m->anyread = 1;
return doreadmsg(2,newargv,p);
}
/* display message on the crt given msg number */
int
doreadmsg(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct mbx *m;
register int c, col, lin;
char buf[MAXCOL+2], *cp, *cp2;
int msg, cnt, i, usemore, verbose, mbxheader, pathcol;
int header, lastheader;
long size;
m = (struct mbx *) p;
if (m->mfile == NULL) {
printf(Nomail);
return 0;
}
if(m->type == TELNET || m->type == TIP)
usemore = 1; /* Display More prompt */
else
usemore = 0;
lin = MAXLIN-1;
for(i = 1; i < argc; ++i) {
msg = atoi(argv[i]);
if( msg < 1 || msg > m->nmsgs) {
printf(Badmsg,msg);
return 0;
}
fseek(m->mfile,m->mbox[msg].start,0);
size = m->mbox[msg].size;
m->current = msg;
header = NOHEADER;
mbxheader = 0;
if(*argv[0] == 'v')
verbose = 1; /* display all header lines */
else
verbose = 0;
printf("Message #%d %s\n", msg,
m->mbox[msg].status & BM_DELETE ? "[Deleted]" : "");
if ((m->mbox[msg].status & BM_READ) == 0) {
m->mbox[msg].status |= BM_READ;
m->change = 1;
m->newmsgs--;
}
--lin;
col = 0;
while (!feof(m->mfile) && size > 0) {
for (col = 0; col < MAXCOL;) {
c = getc(m->mfile);
size--;
if (feof(m->mfile) || size == 0) /* end this line */
break;
if (c == '\t') {
cnt = col + 8 - (col & 7);
if (cnt >= MAXCOL) /* end this line */
break;
while (col < cnt)
buf[col++] = ' ';
} else {
if (c == '\n')
break;
buf[col++] = c;
}
}
if(col < MAXCOL)
buf[col++] = '\n';
buf[col] = '\0';
if(mbxheader > 0) {
/* Digest R: lines and display as a Path: line */
if(strncmp(buf,"R:",2) != 0 ||
(cp = strchr(buf,'@')) == NULL) {
putchar('\n');
mbxheader = -1; /* don't get here again */
verbose = 1;
}
else {
if(*(++cp) == ':')
++cp;
for(cp2 = cp; isalnum(*cp2); ++cp2) ;
*cp2 = '\0';
if(mbxheader++ == 1) {
fputs("Path: ",stdout);
pathcol = 5;
--lin;
}
else {
putchar('!');
if(++pathcol + strlen(cp) > MAXCOL-3){
fputs("\n ",stdout);
pathcol = 5;
--lin;
}
}
fputs(cp,stdout);
pathcol += strlen(cp);
++lin; /* to allow for not printing it later */
}
}
if(col == 1 && !verbose && !mbxheader)
/* last header line reached */
mbxheader = 1;
if(verbose)
fputs(buf,stdout);
if(!verbose && !mbxheader){
lastheader = header;
if(!isspace(*buf))
header = htype(buf);
else
header = lastheader;
switch(header) {
case TO:
case CC:
case FROM:
case DATE:
case SUBJECT:
case APPARTO:
case ORGANIZATION:
fputs(buf,stdout);
break;
default:
++lin;
}
}
col = 0;
if(usemore && --lin == 0){
c = tkeywait("--More--",0);
lin = MAXLIN-1;
if(c == -1 || c == 'q' || c == 'Q')
break;
if(c == '\n' || c == '\r')
lin = 1;
}
}
}
return 0;
}
/* Set up m->to when replying to a message. The subject is returned in
* m->line.
*/
int
mbx_reply(argc,argv,m,cclist,rhdr)
int argc;
char *argv[];
struct mbx *m;
struct list **cclist; /* Pointer to buffer for pointers to cc recipients */
char **rhdr; /* Pointer to buffer for extra reply headers */
{
char subject[MBXLINE], *msgid = NULL, *date = NULL;
char *cp;
int msg, lastheader, header = NOHEADER;
long size;
/* Free anything that might be allocated
* since the last call to mbx_to() or mbx_reply()
*/
free(m->to);
m->to = NULL;
free(m->tofrom);
m->tofrom = NULL;
free(m->tomsgid);
m->tomsgid = NULL;
free(m->origto);
m->origto = NULL;
subject[0] = '\0';
if(argc == 1)
msg = m->current;
else
msg = atoi(argv[1]);
if (m->mfile == NULL) {
if(m->sid & MBX_SID)
fputs("NO - ",stdout);
puts(Nomail);
return 0;
}
if(msg < 1 || msg > m->nmsgs) {
if(m->sid & MBX_SID)
fputs("NO - ",stdout);
puts(Badmsg);
return -1;
}
fseek(m->mfile,m->mbox[msg].start,0);
size = m->mbox[msg].size;
m->current = msg;
while(size > 0 && fgets(m->line,MBXLINE-1,m->mfile) != NULL) {
size -= strlen(m->line);
if(m->line[0] == '\n') /* end of header */
break;
rip(m->line);
lastheader = header;
if(!isspace(m->line[0])) {
header = htype(m->line);
lastheader = NOHEADER;
}
switch(header) {
case SUBJECT:
if(strlen(m->line) > 11 && !strnicmp(&m->line[9],"Re:",3))
strcpy(subject,&m->line[9]);
else
sprintf(subject,"Re: %s",&m->line[9]);
break;
case FROM:
if(m->to == NULL && (cp = getaddress(m->line,0)) !=
NULL)
m->to = strdup(cp);
break;
case REPLYTO:
if((cp = getaddress(m->line,0)) != NULL) {
free(m->to);
m->to = strdup(cp);
}
break;
case MSGID:
free(msgid);
msgid = strdup(&m->line[12]);
break;
case DATE:
free(date);
date = strdup(&m->line[6]);
break;
case TO:
case CC:
case APPARTO:
/* Get addresses on To, Cc and Apparently-To lines */
cp = m->line;
m->line[strlen(cp)+1] = '\0'; /* add extra null at end */
for(;;) {
if((cp = getaddress(cp,lastheader == header ||
cp != m->line)) == NULL)
break;
addlist(cclist,cp,0);
/* skip to next address, if any */
cp += strlen(cp) + 1;
}
break;
}
}
if(msgid != NULL || date != NULL) {
*rhdr = mallocw(LINELEN);
sprintf(*rhdr,"In-Reply-To: your message ");
if(date != NULL) {
sprintf(m->line,"of %s.\n",date);
strcat(*rhdr,m->line);
if(msgid != NULL)
strcat(*rhdr," ");
}
if(msgid != NULL) {
sprintf(m->line,"%s\n",msgid);
strcat(*rhdr,m->line);
}
free(msgid);
free(date);
}
strcpy(m->line,subject);
return 0;
}
void
scanmail(m) /* Get any new mail */
struct mbx *m;
{
FILE *nfile;
int ret, cnt;
char buf[256];
long diff;
if ((diff = isnewmail(m)) == 0L)
return;
if(lockit(m))
return;
if(m->mfile == NULL || diff < 0L) {
/* This is the first time scanmail is called, or the
* mail file size has decreased. In the latter case,
* any changes we did to this area will be lost, but this
* is not fatal.
*/
initnotes(m);
rmlock(Mailspool,m->area);
return;
}
sprintf(buf,"%s/%s.txt",Mailspool,m->area);
if ((nfile = fopen(buf,READ_TEXT)) == NULL)
printf(Noaccess,buf);
else {
/* rewind tempfile */
fseek(m->mfile,0L,0);
cnt = m->nmsgs;
/* Reread all messages since size they may have changed
* in size after a X-Forwarded-To line was added.
*/
m->nmsgs = 0;
ret = readnotes(m,nfile,1); /* get the mail */
m->newmsgs += m->nmsgs - cnt;
m->mboxsize = ftell(nfile);
if(!stricmp(m->name,m->area))
m->mysize = m->mboxsize;
(void) fclose(nfile);
if (ret != 0)
printf("Error updating mail file\n");
}
rmlock(Mailspool,m->area);
}
/* Check the current mailbox to see if new mail has arrived.
* Returns the difference in size.
*/
static long
isnewmail(m)
struct mbx *m;
{
char buf[256];
sprintf(buf,"%s/%s.txt",Mailspool,m->area);
return fsize(buf) - m->mboxsize;
}
/* Check if the private mail area has changed */
long
isnewprivmail(m)
struct mbx *m;
{
long cnt;
char buf[256];
sprintf(buf,"%s/%s.txt",Mailspool,m->name);
cnt = m->mysize;
m->mysize = fsize(buf);
return m->mysize - cnt; /* != 0 not more than once */
}
/* This function returns the length of a file. The proper thing would be
* to use stat(), but it fails when using DesqView together with Turbo-C
* code.
*/
static long
fsize(name)
char *name;
{
long cnt;
FILE *fp;
if((fp = fopen(name,READ_TEXT)) == NULL)
return -1L;
fseek(fp,0L,2);
cnt = ftell(fp);
fclose(fp);
return cnt;
}
/* close the temporary mail file */
static void
mfclose(m)
struct mbx *m;
{
if(m->mfile != NULL)
fclose(m->mfile);
m->mfile = NULL;
#ifdef SETVBUF
free(m->stdoutbuf);
m->stdoutbuf = NULL;
#endif
}
/* Print prompt and read one character, telnet version */
static int
tkeywait(prompt,flush)
char *prompt; /* Optional prompt */
int flush; /* Flush queued input? */
{
int c, i, oldimode,oldomode;
if(flush && socklen(fileno(stdin),0) != 0)
recv_mbuf(fileno(stdin),NULL,0,NULL,0); /* flush */
if(prompt == NULL)
prompt = "Hit enter to continue";
printf("%s%c%c%c",prompt,IAC,WILL,TN_ECHO);
fflush(stdout);
/* discard the response */
oldimode = fmode(stdin,STREAM_BINARY);
oldomode = fmode(stdout,STREAM_BINARY);
while((c = getchar()) == IAC){
c = getchar();
if(c > 250 && c < 255)
getchar();
}
fmode(stdout,oldomode);
fmode(stdin,oldimode);
/* Get rid of the prompt */
for(i=strlen(prompt);i != 0;i--)
putchar('\b');
for(i=strlen(prompt);i != 0;i--)
putchar(' ');
for(i=strlen(prompt);i != 0;i--)
putchar('\b');
printf("%c%c%c",IAC,WONT,TN_ECHO);
fflush(stdout);
return c;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -