/* misc.c -- handles: stristr() split() maskhost() copyfile() movefile() fixfrom() dumplots() daysago() logging things queueing output for the bot (msg and help) resync buffers for sharebots help system motd display and %var substitution note system (will be in Tcl soon i hope) dprintf'ized, 12dec95 */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include "eggdrop.h" #include "proto.h" extern int serv; extern char notefile[]; extern int dcc_total; extern struct dcc_t dcc[]; extern char helpdir[]; extern char version[]; extern char botname[]; extern char origbotname[]; extern char admin[]; extern int require_p; extern int backgrd; extern int con_chan; extern int term_z; extern int use_stderr; extern char motdfile[]; extern char cx_file[]; extern int cx_line; extern char ver[]; extern char textdir[]; extern int strict_host; /* whether or not to display the time with console output */ int shtime=1; /* logfile names */ char *logfile[MAXLOGS]; /* logfile masks */ int logmask[MAXLOGS]; /* logfile channels */ char *logchan[MAXLOGS]; /* console mask */ int conmask=LOG_MODES|LOG_CMDS|LOG_MISC; /* total messages queued on main queue */ int mtot=0; /* total messages queued on help queue */ int htot=0; struct msgq { int sock; char *msg; struct msgq *next; } *mq=NULL,*hq=NULL; /* store info for clone bots */ struct tandbuf { char bot[10]; time_t timer; struct msgq *q; } tbuf[5]; /* expected memory usage */ int expmem_misc() { int tot=0; struct msgq *m=mq,*h=hq; while (m!=NULL) { tot+=strlen(m->msg)+1; tot+=sizeof(struct msgq); m=m->next; } while (h!=NULL) { tot+=strlen(h->msg)+1; tot+=sizeof(struct msgq); h=h->next; } return tot; } void init_misc() { int i; for (i=0; i<5; i++) { tbuf[i].q=NULL; tbuf[i].bot[0]=0; } } /***** MISC FUNCTIONS *****/ #define upcase(c) (((c)>='a' && (c)<='z') ? (c)-'a'+'A' : (c)) /* determine if littles is contained in bigs (ignoring case) */ /* if so: return pointer to the littles in bigs */ /* if not: return NULL */ char *stristr(bigs,littles) char *bigs,*littles; { char *st=bigs,*p,*q; while (1) { if (!*st) return NULL; p=littles; q=st; while ((*p) && (*q) && (upcase(*p)==upcase(*q))) { p++; q++; } if ((!*q) && (*p)) return NULL; /* premature end of bigs */ if (!*p) return st; /* found it! */ st++; /* try again */ } } #if !HAVE_STRCASECMP /* unixware has no strcasecmp() without linking in a hefty library */ int strcasecmp(s1,s2) char *s1,*s2; { while ((*s1) && (*s2) && (upcase(*s1)==upcase(*s2))) { s1++; s2++; } return upcase(*s1)-upcase(*s2); } #endif /* split first word off of rest and put it in first */ void splitc(first,rest,divider) char *first,*rest; char divider; { char *p; p=strchr(rest,divider); if (p==NULL) { if ((first!=rest)&&(first!=NULL)) first[0]=0; return; } *p=0; if (first!=NULL) strcpy(first,rest); if (first!=rest) strcpy(rest,p+1); } void split(first,rest) char *first,*rest; { splitc(first,rest,' '); } void splitnick(first,rest) char *first,*rest; { splitc(first,rest,'!'); } void nsplit(first,rest) char *first,*rest; { split(first,rest); if (first!=NULL) if (!first[0]) { strcpy(first,rest); rest[0]=0; } } /* convert "abc!user@a.b.host" into "*!user@*.b.host" or "abc!user@1.2.3.4" into "*!user@1.2.3.*" */ void maskhost(s,nw) char *s; char *nw; { char *p,*q,xx[150]; strcpy(xx,s); p=strchr(xx,'!'); if (p!=NULL) { /* copy username over, quoting '?' and '*' */ char *dest=xx,*src=p+1; while (*src) { if ((*src=='*')||(*src=='?')) *dest++='\\'; *dest++=*src++; } *dest=0; if (strlen(dest)>10) { /* truncate */ p=strchr(xx,'@'); if (p!=NULL) { if (*(dest+8)=='\\') { *(dest+8)='*'; strcpy(dest+9,p); } else { *(dest+9)='*'; strcpy(dest+10,p); } } } } p=strchr(xx,'@'); if (p!=NULL) { q=strchr(p,'.'); if (q==NULL) { /* form xx@yy -> very bizarre */ sprintf(nw,"*!%s",xx); return; } if (strchr(q+1,'.')==NULL) { /* form xx@yy.com -> don't truncate */ sprintf(nw,"*!%s",xx); return; } if ((xx[strlen(xx)-1] >= '0') && (xx[strlen(xx)-1]<='9')) { /* ip number -> xx@#.#.#.* */ q=strrchr(p,'.'); if (q!=NULL) strcpy(q,".*"); sprintf(nw,"*!%s",xx); return; } /* form xx@yy.zz.etc.edu or whatever -> xx@*.zz.etc.edu */ if (q!=NULL) { *(p+1)='*'; strcpy(p+2,q); } sprintf(nw,"*!%s",xx); } else strcpy(nw,"*"); } /* copy a file from one place to another (possibly erasing old copy) */ /* returns 0 if OK */ int copyfile(oldpath,newpath) char *oldpath,*newpath; { int fi,fo,x; char buf[512]; struct stat st; fi=open(oldpath,O_RDONLY,0); if (fi<0) return 1; fstat(fi,&st); if (!(st.st_mode & S_IFREG)) return 3; fo=creat(newpath,(int)(st.st_mode & 0777)); if (fo<0) return 2; for (x=1; x>0; ) { x=read(fi,buf,512); if (x>0) write(fo,buf,x); } close(fo); close(fi); return 0; } int movefile(oldpath,newpath) char *oldpath,*newpath; { int x=copyfile(oldpath,newpath); if (x==0) unlink(oldpath); return x; } /* make nick!~user@host into nick!user@host if necessary */ void fixfrom(s) char *s; { char nick[NICKLEN],from[UHOSTLEN]; if (strict_host) return; if (s==NULL) return; if (strchr(s,'@')==NULL) return; strcpy(from,s); splitnick(nick,from); if (from[0]=='~') strcpy(from,&from[1]); sprintf(s,"%s!%s",nick,from); } /* dump a potentially super-long string of text */ /* assume prefix 20 chars or less */ void dumplots(idx,prefix,data) int idx; char *prefix,*data; { char *p=data,*q,*n,c; if (!(*data)) { dprintf(idx,"%s\n",prefix); return; } while (strlen(p)>490) { q=p+490; /* search for embedded linefeed first */ n=strchr(p,'\n'); if ((n!=NULL) && (n 86400) { int days=(now-then)/86400; sprintf(out,"%d day%s ago",days,(days==1)?"":"s"); return; } strcpy(s,ctime(&then)); s[16]=0; strcpy(out,&s[11]); } /***** LOGGING *****/ /* log something */ /* putlog(level,channel_name,format,...); */ void putlog(va_alist) va_dcl { FILE *f; va_list va; int i,type; char *format,*chname,s[570],s1[40],s2[570]; time_t tt; va_start(va); type=va_arg(va,int); chname=va_arg(va,char *); format=va_arg(va,char *); vsprintf(s,format,va); if (s[0]==0) strcpy(s,"\n"); else if (shtime) { tt=time(NULL); strcpy(s1,ctime(&tt)); strcpy(s1,&s1[11]); s1[5]=0; sprintf(s2,"[%s] %s\n",s1,s); strcpy(s,s2); } else strcat(s,"\n"); if (!use_stderr) { for (i=0; icon_flags&type)) { if ((chname[0]=='*') || (dcc[i].u.chat->con_chan[0]=='*') || (strcasecmp(chname,dcc[i].u.chat->con_chan)==0)) dprintf(i,"%s",s); } if ((type&LOG_MISC) && (use_stderr)) { vsprintf(s,format,va); tprintf(STDERR,"%s\n",s); } va_end(va); } /***** BOT AND HELPBOT SERVER QUEUES *****/ /* queue a msg on one of the msg queues */ struct msgq *q_msg(qq,sock,s) struct msgq *qq; int sock; char *s; { struct msgq *q; int cnt; if (qq==NULL) { q=(struct msgq *)nmalloc(sizeof(struct msgq)); q->sock=sock; q->next=NULL; q->msg=(char *)nmalloc(strlen(s)+1); strcpy(q->msg,s); return q; } cnt=0; q=qq; while (q->next!=NULL) { q=q->next; cnt++; } if (cnt>MAXQMSG) return NULL; /* return null: did not alter queue */ q->next=(struct msgq *)nmalloc(sizeof(struct msgq)); q=q->next; q->sock=sock; q->next=NULL; q->msg=(char *)nmalloc(strlen(s)+1); strcpy(q->msg,s); return qq; } /* use when sending msgs... will spread them out so there's no flooding */ void mprintf(va_alist) va_dcl { char s[512]; int sock; char *format; va_list va; struct msgq *q; static int warned=0; va_start(va); sock=va_arg(va,int); format=va_arg(va,char *); vsprintf(s,format,va); va_end(va); q=q_msg(mq,sock,s); if (q!=NULL) { mq=q; mtot++; warned=0; } else { if (!warned) putlog(LOG_MISC,"*","!!! OVER MAXIMUM MSG QUEUE"); warned=1; } } /* use when sending help msgs (different queue) */ void hprintf(va_alist) va_dcl { char s[512]; int sock; char *format; va_list va; struct msgq *q; static int warned=0; va_start(va); sock=va_arg(va,int); format=va_arg(va,char *); vsprintf(s,format,va); va_end(va); q=q_msg(hq,sock,s); if (q!=NULL) { hq=q; htot++; warned=0; } else { if (!warned) putlog(LOG_MISC,"*","!!! OVER MAXIMUM HELP QUEUE"); warned=1; } } /* called periodically to shove out another queued item */ void deq_msg() { static which=0; /* to alternate which queue is pushed */ struct msgq *q; q=(which ? hq : mq); if (q==NULL) q=(which ? mq : hq); /* chosen one is empty? switch off */ if (q==NULL) return; /* both queues empty */ write(q->sock,q->msg,strlen(q->msg)); if (q==mq) { mq=mq->next; mtot--; } else { hq=hq->next; htot--; } nfree(q->msg); nfree(q); } /***** RESYNC BUFFERS *****/ /* create a tandem buffer for 'bot' */ void new_tbuf(bot) char *bot; { int i; for (i=0; i<5; i++) if (tbuf[i].bot[0]==0) { /* this one is empty */ strcpy(tbuf[i].bot,bot); tbuf[i].q=NULL; tbuf[i].timer=time(NULL); putlog(LOG_MISC,"*","Creating resync buffer for %s",bot); return; } } /* flush a certain bot's tbuf */ void flush_tbuf(bot) char *bot; { int i; struct msgq *q; for (i=0; i<5; i++) if (strcasecmp(tbuf[i].bot,bot)==0) { while (tbuf[i].q!=NULL) { q=tbuf[i].q; tbuf[i].q=tbuf[i].q->next; nfree(q->msg); nfree(q); } tbuf[i].bot[0]=0; } } /* flush all tbufs older than 15 minutes */ void check_expired_tbufs() { int i; time_t now=time(NULL); struct msgq *q; for (i=0; i<5; i++) if (tbuf[i].bot[0]) { if (now-tbuf[i].timer > 900) { /* EXPIRED */ while (tbuf[i].q!=NULL) { q=tbuf[i].q; tbuf[i].q=tbuf[i].q->next; nfree(q->msg); nfree(q); } putlog(LOG_MISC,"*","Flushing resync buffer for clonebot %s.", tbuf[i].bot); tbuf[i].bot[0]=0; } } } /* add stuff to the resync buffers */ void q_resync(s) char *s; { int i; struct msgq *q; for (i=0; i<5; i++) if (tbuf[i].bot[0]) { q=q_msg(tbuf[i].q,0,s); if (q!=NULL) tbuf[i].q=q; } } /* is bot in resync list? */ int can_resync(bot) char *bot; { int i; for (i=0; i<5; i++) if (strcasecmp(bot,tbuf[i].bot)==0) return 1; return 0; } /* dump the resync buffer for a bot */ void dump_resync(z,bot) int z; char *bot; { int i; struct msgq *q; for (i=0; i<5; i++) if (strcasecmp(bot,tbuf[i].bot)==0) { while (tbuf[i].q!=NULL) { q=tbuf[i].q; tbuf[i].q=tbuf[i].q->next; tprintf(z,"%s",q->msg); nfree(q->msg); nfree(q); } tbuf[i].bot[0]=0; return; } } /* substitute %x codes in help files */ /* %B = bot nickname */ /* %V = version */ /* %C = list of channels i monitor */ /* %E = eggdrop banner */ /* %A = admin line */ /* %T = current time ("14:15") */ /* %N = user's nickname */ void help_subst(s,nick,oper,master) char *s,*nick; int oper,master; { char xx[512],sub[161],*p,c; int i,blind=0; time_t tt; strcpy(xx,s); s[0]=0; p=strchr(xx,'%'); while (p!=NULL) { c=*(p+1); sub[0]=0; *p=0; if (!blind) strcat(s,xx); switch(c) { case 'B': strcpy(sub,botname); break; case 'V': strcpy(sub,ver); break; case 'C': getchanlist(sub,160); break; case 'E': strcpy(sub,version); break; case 'A': strcpy(sub,admin); break; case 'T': tt=time(NULL); strcpy(sub,ctime(&tt)); strcpy(sub,&sub[11]); sub[5]=0; break; case 'N': strcpy(sub,nick); break; case '(': if (!oper) blind=1; break; case ')': blind=0; break; case '[': if (!master) blind=1; break; case ']': blind=0; break; case '%': strcpy(sub,"%"); break; default: strcpy(sub,"%_"); sub[1]=c; break; } i=strlen(sub); if (!blind) strcat(s,sub); if (c!=0) strcpy(xx,p+2); else xx[0]=0; p=strchr(xx,'%'); } if (!blind) strcat(s,xx); if (strlen(s)>120) s[120]=0; } void showhelp(who,file,oper,master) char *who,*file; int oper,master; { FILE *f; char s[121],*p; for (p=file; *p!=0; p++) if ((*p==' ') || (*p=='/')) *p='.'; sprintf(s,"%s%s",helpdir,file); f=fopen(s,"r"); if (f==NULL) { hprintf(serv,"NOTICE %s :No help available on that.\n",who); return; } if (!is_file(s)) { fclose(f); hprintf(serv,"NOTICE %s :'%s' is not a normal file!\n",who,s); return; } if (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (((strcasecmp(s,"!master")==0) && (!master)) || ((strcasecmp(s,"!op")==0) && (!oper))) { hprintf(serv,"NOTICE %s :No help available on that.\n",who); return; } } } if (!feof(f)) if ((strcasecmp(s,"!master")!=0) && (strcasecmp(s,"!op")!=0)) { help_subst(s,who,oper,master); if (s[0]) hprintf(serv,"NOTICE %s :%s\n",who,s); } while (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!s[0]) strcpy(s," "); help_subst(s,who,oper,master); if (s[0]) hprintf(serv,"NOTICE %s :%s\n",who,s); } } fclose(f); } void showtext(who,file,oper,master) char *who,*file; int oper,master; { FILE *f; char s[121],*p; for (p=file; *p!=0; p++) if ((*p==' ') || (*p=='/')) *p='.'; sprintf(s,"%s%s",textdir,file); f=fopen(s,"r"); if (f==NULL) return; if (!is_file(s)) { fclose(f); hprintf(serv,"NOTICE %s :'%s' is not a normal file!\n",who,s); return; } if (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (((strcasecmp(s,"!master")==0) && (!master)) || ((strcasecmp(s,"!op")==0) && (!oper))) return; } } if (!feof(f)) if ((strcasecmp(s,"!master")!=0) && (strcasecmp(s,"!op")!=0)) { help_subst(s,who,oper,master); if (s[0]) hprintf(serv,"NOTICE %s :%s\n",who,s); } while (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!s[0]) strcpy(s," "); help_subst(s,who,oper,master); if (s[0]) hprintf(serv,"NOTICE %s :%s\n",who,s); } } fclose(f); } void tellhelp(idx,file,oper,master) int idx,oper,master; char *file; { FILE *f; char s[121],*p; for (p=file; *p!=0; p++) if ((*p==' ') || (*p=='/')) *p='.'; sprintf(s,"%sdcc.%s",helpdir,file); f=fopen(s,"r"); if (f==NULL) { dprintf(idx,"No help available on that.\n"); return; } if (!is_file(s)) { fclose(f); dprintf(idx,"### '%s' is not a normal file!\n",s); return; } if (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (((strcasecmp(s,"!master")==0) && (!master)) || ((strcasecmp(s,"!op")==0) && (!oper))) { dprintf(idx,"No help available on that.\n"); return; } } } if (!feof(f)) if ((strcasecmp(s,"!master")!=0) && (strcasecmp(s,"!op")!=0)) { help_subst(s,dcc[idx].nick,oper,master); if (s[0]) dprintf(idx,"%s\n",s); } while (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!s[0]) strcpy(s," "); help_subst(s,dcc[idx].nick,oper,master); if (s[0]) dprintf(idx,"%s\n",s); } } fclose(f); } void telltext(idx,file,oper,master) int idx,oper,master; char *file; { FILE *f; char s[121],*p; for (p=file; *p!=0; p++) if ((*p==' ') || (*p=='/')) *p='.'; sprintf(s,"%s%s",textdir,file); f=fopen(s,"r"); if (f==NULL) return; if (!is_file(s)) { fclose(f); dprintf(idx,"### '%s' is not a normal file!\n",s); return; } if (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (((strcasecmp(s,"!master")==0) && (!master)) || ((strcasecmp(s,"!op")==0) && (!oper))) return; } } if (!feof(f)) if ((strcasecmp(s,"!master")!=0) && (strcasecmp(s,"!op")!=0)) { help_subst(s,dcc[idx].nick,oper,master); if (s[0]) dprintf(idx,"%s\n",s); } while (!feof(f)) { fgets(s,120,f); if (!feof(f)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!s[0]) strcpy(s," "); help_subst(s,dcc[idx].nick,oper,master); if (s[0]) dprintf(idx,"%s\n",s); } } fclose(f); } /* show motd to dcc chatter */ void show_motd(idx) int idx; { FILE *vv; char s[121]; vv=fopen(motdfile,"r"); if (vv!=NULL) { if (!is_file(motdfile)) { fclose(vv); dprintf(idx,"### MOTD is not a normal file!\n"); return; } dprintf(idx,"\n"); while (!feof(vv)) { fgets(s,120,vv); if (!feof(vv)) { if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!s[0]) strcpy(s," "); help_subst(s,dcc[idx].nick,!(dcc[idx].u.chat->status&STAT_PARTY), dcc[idx].u.chat->status&STAT_MASTER); if (s[0]) dprintf(idx,"%s\n",s); } } fclose(vv); dprintf(idx,"\n"); } } /***** NOTES *****/ /* determine how many notes are waiting for a user */ int num_notes(user) char *user; { int tot=0; FILE *f; char s[513],to[15]; if (!notefile[0]) return 0; f=fopen(notefile,"r"); if (f==NULL) return 0; while (!feof(f)) { fgets(s,512,f); if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!feof(f)) { rmspace(s); if ((s[0]) && (s[0]!='#') && (s[0]!=';')) { /* not comment */ split(to,s); if (strcasecmp(to,user)==0) tot++; } } } fclose(f); return tot; } /* add note to notefile */ int add_note(to,from,msg,idx,echo) char *to,*from,*msg; int idx,echo; { FILE *f; int i,sock; char *p,botf[81],ss[81]; if (strlen(msg)>450) msg[450]=0; /* notes have a limit */ /* note length + PRIVMSG header + nickname + date must be <512 */ p=strchr(to,'@'); if (p!=NULL) { /* cross-bot note */ *p=0; p++; if (strcasecmp(p,origbotname)==0) /* to me?? */ return add_note(to,from,msg,idx,echo); /* start over, dimwit. */ if (strcasecmp(from,origbotname)!=0) sprintf(botf,"%s@%s",from,origbotname); else strcpy(botf,origbotname); i=nextbot(p); if (i<0) { if (idx>=0) dprintf(idx,"That bot isn't here.\n"); return 0; } if ((idx>=0) && (echo)) dprintf(idx,"-> %s@%s: %s\n",to,p,msg); tprintf(dcc[i].sock,"priv %s %s@%s %s\n",botf,to,p,msg); return 1; } /* might be form "sock:nick" */ splitc(ss,to,':'); if (!ss[0]) sock=(-1); else sock=atoi(ss); if (!is_user(to)) { if (idx>=0) dprintf(idx,"I don't know anyone by that name.\n"); return 0; } if (get_attr_handle(to) & USER_BOT) { if (idx>=0) dprintf(idx,"That's a bot. You can't leave notes for a bot.\n"); return 0; } for (i=0; iaway!=NULL) && (idx!=(-2))) { /* only check away if it's not from a bot */ aok=0; if (idx>=0) dprintf(idx,"%s is away: %s\n",dcc[i].nick,dcc[i].u.chat->away); } if (dcc[i].type==DCC_FILES) if ((dcc[i].u.file->chat->away!=NULL) && (idx!=(-2))) { aok=0; if (idx>=0) dprintf(idx,"%s is away: %s\n",dcc[i].nick, dcc[i].u.file->chat->away); } if (aok) { if (idx==(-2)) dprintf(i,"*** [%s] %s\n",from,msg); else dprintf(i,"%cNote [%s]: %s\n",7,from,msg); if ((idx>=0) && (echo)) dprintf(idx,"-> %s: %s\n",to,msg); return 1; } } } if (notefile[0]==0) { if (idx>=0) dprintf(idx,"Notes are not supported by this bot.\n"); return 0; } if (idx==(-2)) return 1; /* error msg from a tandembot: don't store */ f=fopen(notefile,"a"); if (f==NULL) f=fopen(notefile,"w"); if (f==NULL) { if (idx>=0) dprintf(idx,"Can't create notefile. Sorry.\n"); putlog(LOG_MISC,"*","Notefile unreachable!"); return 0; } fprintf(f,"%s %s %lu %s\n",to,from,time(NULL),msg); fclose(f); if (idx>=0) dprintf(idx,"Stored message.\n"); return 2; } /* rd=-1 : index rd=0 : read all msgs rd>0 : read msg #n idx=-1 : /msg */ void notes_read(hand,nick,rd,idx) char *hand,*nick; int rd,idx; { FILE *f; char s[601],to[15],dt[81],from[81]; time_t tt; int ix=1; if (!notefile[0]) { if (idx>=0) dprintf(idx,"You have no messages.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); return; } f=fopen(notefile,"r"); if (f==NULL) { if (idx>=0) dprintf(idx,"You have no messages.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); return; } while (!feof(f)) { fgets(s,600,f); if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!feof(f)) { rmspace(s); if ((s[0]) && (s[0]!='#') & (s[0]!=';')) { /* not comment */ split(to,s); if (strcasecmp(to,hand)==0) { split(from,s); split(dt,s); tt=atol(dt); strcpy(dt,ctime(&tt)); dt[16]=0; strcpy(dt,&dt[4]); if ((ix==rd) || (rd==0)) { if (idx>=0) dprintf(idx,"%2d. %s (%s): %s\n",ix,from,dt,s); else hprintf(serv,"NOTICE %s :%2d. %s (%s): %s\n",nick,ix,from, dt,s); } if (rd<0) { if (idx>=0) { if (ix==1) dprintf(idx,"### You have the following notes waiting:\n"); dprintf(idx," %2d. %s (%s)\n",ix,from,dt); } else hprintf(serv,"NOTICE %s :%2d. %s (%s)\n",nick,ix,from,dt); } ix++; } } } } fclose(f); if ((rd>=ix) && (rd>0)) { if (idx>=0) dprintf(idx,"You don't have that many messages.\n"); else hprintf(serv,"NOTICE %s :You don't have that many messages.\n",nick); } if (rd<0) { if (ix==1) { if (idx>=0) dprintf(idx,"You have no messages waiting.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); } else { if (idx>=0) dprintf(idx,"### Use '.notes read' to read them.\n"); else hprintf(serv,"NOTICE %s :(%d total)\n",nick,ix-1); } } if ((rd==0) && (ix==1)) { if (idx>=0) dprintf(idx,"You have no messages waiting.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); } } void notes_del(hand,nick,dl,idx) char *nick,*hand; int dl,idx; { FILE *f,*g; char s[513],to[81]; int in=1; if (!notefile[0]) { if (idx>=0) dprintf(idx,"You have no messages.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); return; } f=fopen(notefile,"r"); if (f==NULL) { if (idx>=0) dprintf(idx,"You have no messages.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); return; } sprintf(s,"%s~new",notefile); g=fopen(s,"w"); if (g==NULL) { if (idx>=0) dprintf(idx,"Can't modify the note file. :(\n"); else hprintf(serv,"NOTICE %s :Can't modify the note file. :(\n",nick); fclose(f); return; } while (!feof(f)) { fgets(s,512,f); if (s[strlen(s)-1]=='\n') s[strlen(s)-1]=0; if (!feof(f)) { rmspace(s); if ((s[0]) && (s[0]!='#') && (s[0]!=';')) { /* not comment */ split(to,s); if (strcasecmp(to,hand)==0) { if ((dl>0) && (in!=dl)) fprintf(g,"%s %s\n",to,s); in++; } else fprintf(g,"%s %s\n",to,s); } else fprintf(g,"%s\n",s); } } fclose(f); fclose(g); unlink(notefile); sprintf(s,"%s~new",notefile); #ifdef RENAME rename(s,notefile); #else movefile(s,notefile); #endif if ((dl>=in) && (dl>0)) { if (idx>=0) dprintf(idx,"You don't have that many messages.\n"); else hprintf(serv,"NOTICE %s :You don't have that many messages.\n", nick); } else if (in==1) { if (idx>=0) dprintf(idx,"You have no messages.\n"); else hprintf(serv,"NOTICE %s :You have no messages.\n",nick); } else { if (dl==0) { if (idx>=0) dprintf(idx,"Erased all notes.\n"); else hprintf(serv,"NOTICE %s :Erased all notes.\n",nick); } else { if (idx>=0) dprintf(idx,"Erased #%d; %d left.\n",dl,in-2); else hprintf(serv,"NOTICE %s :Erased #%d; %d left.\n",nick,dl,in-2); } } }