home *** CD-ROM | disk | FTP | other *** search
/ The Net: Ultimate Internet Guide / WWLCD1.ISO / pc / java / in4wjcxu / other / irc / ircd / note.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-14  |  103.7 KB  |  2,927 lines

  1. /************************************************************************
  2.  *   IRC - Internet Relay Chat, ircd/note.c
  3.  *   Copyright (C) 1990 Jarle Lyngaas
  4.  *
  5.  *   This program is free software; you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 1, or (at your option)
  8.  *   any later version.
  9.  *
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *   GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program; if not, write to the Free Software
  17.  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19.  
  20. /*
  21.  *        Author: Jarle Lyngaas
  22.  *        E-mail: nmijl@alf.uib.no
  23.  *        On IRC: Wizible
  24.  */
  25.  
  26. #include "struct.h"
  27. #ifdef NPATH
  28. #include "numeric.h"
  29. #include <ctype.h>
  30. #include <stdio.h>
  31. #include <time.h>
  32. #include "common.h"
  33. #include "sys.h"
  34. #include "h.h"
  35.  
  36. #define VERSION "v2.1"
  37.  
  38. #define NOTE_SAVE_FREQUENCY 30 /* Frequency of save time in minutes */
  39. #define NOTE_MAXSERVER_TIME 120 /* Max days for a request in the server */
  40. #define NOTE_MAXSERVER_MESSAGES 2000 /* Max number of requests in the server */
  41. #define NOTE_MAXUSER_MESSAGES 200 /* Max number of requests for each user */
  42. #define NOTE_MAXSERVER_WILDCARDS 200 /* Max number of server toname w.cards */
  43. #define NOTE_MAXUSER_WILDCARDS 5 /* Max number of user toname wildcards */
  44.  
  45. #define MAX_DAYS_NO_USE_SPY 31 /* No match or no user on */
  46. #define SECONDS_WAITFOR_MODE 10
  47. #define LAST_CLIENTS 200 /* More than this on within prev. time gets secret */
  48. /* Jan Kautz 
  49. was:
  50.  
  51. #define BUF_LEN 256
  52. #define MSG_LEN 512
  53.  
  54. */
  55. #define BUF_LEN IRC_SUCKS_LINE_LENGTH
  56. #define MSG_LEN IRC_SUCKS_LINE_LENGTH+2
  57. #define REALLOC_SIZE 1024
  58.  
  59. #define FLAGS_WASOPER (1<<0)
  60. #define FLAGS_SIGNOFF_REMOVE (1<<1)
  61. #define FLAGS_NAME (1<<2)
  62. #define FLAGS_FROM_REG (1<<3)
  63. #define FLAGS_NEWS (1<<4)
  64. #define FLAGS_ON_THIS_SERVER (1<<5)
  65. #define FLAGS_REPEAT_UNTIL_TIMEOUT (1<<6)
  66. #define FLAGS_ALL_NICK_VALID (1<<7)
  67. #define FLAGS_SERVER_GENERATED_NOTICE (1<<8)
  68. #define FLAGS_NICK_AND_WILDCARD_VALID (1<<9)
  69. #define FLAGS_SERVER_GENERATED_DESTINATION (1<<10)
  70. #define FLAGS_DISPLAY_IF_RECEIVED (1<<11)
  71. #define FLAGS_DISPLAY_IF_CORRECT_FOUND (1<<12)
  72. #define FLAGS_DISPLAY_IF_DEST_REGISTER (1<<13)
  73. #define FLAGS_SEND_ONLY_IF_SENDER_ON_IRC (1<<14)
  74. #define FLAGS_NO_NICKCHANGE_SPY (1<<16)
  75. #define FLAGS_SEND_ONLY_IF_THIS_SERVER (1<<17)
  76. #define FLAGS_SEND_ONLY_IF_DESTINATION_OPER (1<<18)
  77. #define FLAGS_SEND_ONLY_IF_NICK_NOT_NAME (1<<19)
  78. #define FLAGS_SEND_ONLY_IF_NOT_EXCEPTION (1<<20)
  79. #define FLAGS_KEY_TO_OPEN_OPER_LOCKS (1<<21)
  80. #define FLAGS_FIND_CORRECT_DEST_SEND_ONCE (1<<22)
  81. #define FLAGS_DISPLAY_CHANNEL_DEST_REGISTER (1<<23)
  82. #define FLAGS_DISPLAY_SERVER_DEST_REGISTER (1<<24)
  83. #define FLAGS_PRIVATE_DISPLAYED (1<<25)
  84. #define FLAGS_REGISTER_NEWNICK (1<<26)
  85. #define FLAGS_NOTICE_RECEIVED_MESSAGE (1<<27)
  86. #define FLAGS_RETURN_CORRECT_DESTINATION (1<<28)
  87. #define FLAGS_NOT_QUEUE_REQUESTS (1<<29)
  88. #define FLAGS_NEWNICK_DISPLAYED (1<<30)
  89.  
  90. #define DupNewString(x,y) if (!StrEq(x,y)) { MyFree(x); DupString(x,y); }  
  91. #define MyEq(x,y) (!myncmp(x,y,strlen(x)))
  92. #define Usermycmp(x,y) mycmp(x,y)
  93. #define Key(sptr) KeyFlags(sptr,-1)
  94. #define Message(msgclient) get_msg(msgclient, 'm')
  95. #define IsOperHere(sptr) (IsOper(sptr) && MyConnect(sptr))
  96. #define NULLCHAR ((char *)0)
  97. #define SPY_CTRLCHAR 13
  98. #define DummyChar '~'
  99.  
  100. /* Using Message(msgclient) to get message part of *any* message
  101.    cause the spy function is an ugly hack saving log in this field - Jarle */
  102.  
  103. typedef struct MsgClient {
  104.             char *fromnick, *fromname, *fromhost, *tonick,
  105.                  *toname, *tohost, *message, *passwd;
  106.             long timeout, time, flags, id;
  107.           } aMsgClient;
  108.   
  109. static int note_mst = NOTE_MAXSERVER_TIME,
  110.            note_mum = NOTE_MAXUSER_MESSAGES,
  111.            note_msm = NOTE_MAXSERVER_MESSAGES,
  112.            note_msw = NOTE_MAXSERVER_WILDCARDS,
  113.            note_muw = NOTE_MAXUSER_WILDCARDS,
  114.            note_msf = NOTE_SAVE_FREQUENCY*60,
  115.            wildcard_index = 0,
  116.            toname_index = 0,
  117.            fromname_index = 0,
  118.            max_toname,
  119.            max_wildcards,
  120.            max_fromname,
  121.            m_id = 0,
  122.            changes_to_save = 0,
  123.            buffer_overload = 0;
  124.  
  125. static long old_clock = 0, old_clock_request = 0;
  126. static aMsgClient **ToNameList, **FromNameList, **WildCardList;
  127. extern aClient *client, *find_person(), *local[];
  128. extern int highest_fd;
  129. extern aChannel *channel;
  130. extern char *MyMalloc(), *MyRealloc(), *myctime();
  131. extern char *myctime();
  132. static char *ptr = "IRCnote", *note_save_filename_tmp, file_inited = 0;
  133.  
  134. static char *UserName(sptr)
  135. aClient *sptr;
  136. {
  137.  if (*(sptr->user->username) != DummyChar) return sptr->user->username;
  138.   else return sptr->user->username+1; 
  139. }
  140.  
  141. static int numeric(string)
  142. char *string;
  143. {
  144.  register char *c = string;
  145.  
  146.  while (*c) if (!isdigit(*c)) return 0; else c++;
  147.  return 1;
  148. }
  149.  
  150. static char *clean_spychar(string)
  151. char *string;
  152. {
  153.  static char buf[MSG_LEN]; 
  154.  char *c, *bp = buf;
  155.  
  156.  for (c = string; *c; c++) if (*c != SPY_CTRLCHAR) *bp++ = *c;
  157.  *bp = 0;
  158.  return buf;
  159. }
  160.  
  161. static char *myitoa(value)
  162. long value;
  163. {
  164.  static char buf[BUF_LEN]; 
  165.   
  166.  sprintf(buf, "%d", value);
  167.  return buf;
  168. }
  169.  
  170. static char *relative_time(seconds)
  171. long seconds;
  172. {
  173.  static char buf[20];
  174.  char *c;
  175.  long d, h, m;
  176.  
  177.  if (seconds < 0) seconds = 0; 
  178.  d = seconds / (3600*24);
  179.  seconds -= d*3600*24;
  180.  h = seconds / 3600;
  181.  seconds -= h*3600;
  182.  m = seconds / 60;
  183.  seconds -= m*60;
  184.  sprintf(buf, "%3dd:%2dh:%2dm", d, h, m);
  185.  c = buf; 
  186.  while (*c) {
  187.               if (*c == ' ') *c = '0';
  188.               c++;
  189.         } 
  190.  return buf;
  191. }
  192.  
  193. static char *mytime(value)
  194. long value;
  195. {
  196.  long clock;
  197.  time(&clock);
  198.  return (relative_time(clock-value));
  199. }
  200.  
  201. static char *get_msg(msgclient, field)
  202. aMsgClient *msgclient;
  203. char field;
  204. {
  205.  char *c = msgclient->message;
  206.  static char buf[MSG_LEN], *empty_char = "";
  207.  int t, p;
  208.  buf[0] = 0;
  209.  
  210.  switch(field) {
  211.      case 'n' : t = 1; break;
  212.      case 'u' : t = 2; break;
  213.      case 'h' : t = 3; break;
  214.      case 'r' : t = 4; break;
  215.      case '1' : t = 5; break;
  216.      case '2' : t = 6; break;
  217.      default: t = 0;
  218.    }
  219.  if (!t) {
  220.            while (*c) c++;
  221.            while (c != msgclient->message && *c != SPY_CTRLCHAR) c--;
  222.            if (*c == SPY_CTRLCHAR) c++;
  223.            return c;
  224.        }
  225.  while(t--) {
  226.       p = 0;
  227.       while (*c && *c != SPY_CTRLCHAR) buf[p++] = *c++;
  228.       if (!*c) return empty_char;
  229.       buf[p] = 0; c++;
  230.   };
  231.  return buf;
  232. }       
  233.  
  234. static void update_spymsg(msgclient)
  235. aMsgClient *msgclient;
  236. {
  237.  long clock, t;
  238.  char *buf, *empty = "-", ctrlbuf[2], mbuf[MSG_LEN]; 
  239.  
  240.  time (&clock);
  241.  mbuf[0] = 0; ctrlbuf[0] = SPY_CTRLCHAR; ctrlbuf[1] = 0;
  242.  
  243.  buf = get_msg(msgclient, 'n'); if (!*buf) buf = empty; 
  244.  strcat(mbuf, buf); strcat(mbuf, ctrlbuf); 
  245.  buf = get_msg(msgclient, 'u'); if (!*buf) buf = empty; 
  246.  strcat(mbuf, buf); strcat(mbuf, ctrlbuf); 
  247.  buf = get_msg(msgclient, 'h'); if (!*buf) buf = empty; 
  248.  strcat(mbuf, buf); strcat(mbuf, ctrlbuf); 
  249.  buf = get_msg(msgclient, 'r'); if (!*buf) buf = empty; 
  250.  strcat(mbuf, buf); strcat(mbuf, ctrlbuf); 
  251.  buf = get_msg(msgclient, '1'); if (!*buf) buf = empty; 
  252.  strcat(mbuf, buf); strcat(mbuf, ctrlbuf); 
  253.  strcat(mbuf, myitoa(clock-msgclient->time)); 
  254.  strcat(mbuf, ctrlbuf); t = MSG_LEN - strlen(mbuf) - 10;
  255.  strncat(mbuf, clean_spychar(Message(msgclient)), t);
  256.  strcat(mbuf, "\0");
  257.  DupNewString(msgclient->message, mbuf);
  258.  changes_to_save = 1;
  259. }
  260.  
  261. static char *wildcards(string)
  262. char *string;
  263. {
  264.  register char *c;
  265.  
  266.  for (c = string; *c; c++) if (*c == '*' || *c == '?') return(c);
  267.  return 0;
  268. }
  269.  
  270. static int only_wildcards(string)
  271. char *string;
  272. {
  273.  register char *c;
  274.  
  275.  for (c = string;*c;c++) 
  276.       if (*c != '*' && *c != '?') return 0;
  277.  return 1;
  278. }
  279.  
  280. static char *split_string(string, field, n)
  281. char *string;
  282. int field, n;
  283. {
  284.  static char buf[MSG_LEN], *empty_char = "";
  285.  char *c = string;
  286.  int p, t;
  287.  buf[0] = 0;
  288.  
  289.  while(field--) {
  290.       p = 0; t = n;
  291.       while (*c) {
  292.             if (*c == ' ' && (field || !--t)) break;
  293.             buf[p++] = *c++;
  294.     }
  295.       if (!*c) if (!field) {
  296.                   buf[p] = 0; return buf;
  297.                 } else return empty_char;
  298.       buf[p] = 0; c++;
  299.   };
  300.  return buf;
  301. }
  302.  
  303. static char *wild_fromnick(nick, msgclient)
  304. char *nick;
  305. aMsgClient *msgclient;
  306. {
  307.  static char buf[BUF_LEN];
  308.  char *msg, *c;
  309.  
  310.  if (msgclient->flags & FLAGS_ALL_NICK_VALID) {
  311.      strcpy(buf, "*"); return buf;
  312.    }
  313.  if (msgclient->flags & FLAGS_NICK_AND_WILDCARD_VALID
  314.      && MyEq(msgclient->fromnick, nick)) {
  315.      strcpy(buf, nick);
  316.      strcat(buf, "*"); return buf;
  317.   }
  318.  if (msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER) {
  319.     msg = Message(msgclient);
  320.     while (*msg == '%') { 
  321.            msg++; c = split_string(msg, 1, 1);
  322.            if (!mycmp(c, nick)) { 
  323.                strcpy(buf, "*");
  324.                return buf;
  325.         }
  326.            while (*msg && *msg != ' ') msg++; if (*msg) msg++;
  327.       }     
  328.   }
  329.  return NULLCHAR;
  330. }
  331.  
  332. static int number_fromname()
  333. {
  334.  register int t, nr = 0;
  335.  long clock;
  336.  
  337.  time (&clock);
  338.  for (t = 1;t <= fromname_index; t++) 
  339.       if (FromNameList[t]->timeout > clock
  340.           && !(FromNameList[t]->flags & FLAGS_SERVER_GENERATED_NOTICE)
  341.           && !(FromNameList[t]->flags & FLAGS_SERVER_GENERATED_DESTINATION)) 
  342.        nr++;
  343.  return nr;         
  344. }
  345.  
  346.  
  347. static int first_tnl_indexnode(name)
  348. char *name;
  349. {
  350.  register int s, t = toname_index+1, b = 0, tname;
  351.  aMsgClient *msgclient;
  352.  
  353.  if (!t) return 0;
  354.  while ((s = (b+t) >> 1) != b) {
  355.        msgclient = ToNameList[s];
  356.        tname = (msgclient->flags & FLAGS_NAME) ? 1 : 0;
  357.        if (mycmp(tname ? msgclient->toname : msgclient->tonick, name) < 0)
  358.         b = s; else t = s;
  359.   }
  360.  return t;
  361. }
  362.  
  363. static int last_tnl_indexnode(name)
  364. char *name;
  365. {
  366.  register int s, t = toname_index+1, b = 0, tname;
  367.  aMsgClient *msgclient;
  368.  
  369.  if (!t) return 0;
  370.  while ((s = (b+t) >> 1) != b) {
  371.        msgclient = ToNameList[s];
  372.        tname = (msgclient->flags & FLAGS_NAME) ? 1 : 0;
  373.        if (mycmp(tname ? msgclient->toname : msgclient->tonick, name) > 0)
  374.         t = s; else b = s;
  375.    }
  376.  return b;
  377. }
  378.  
  379. static int first_fnl_indexnode(fromname)
  380. char *fromname;
  381. {
  382.  register int s, t = fromname_index+1, b = 0;
  383.  
  384.  if (!t) return 0;
  385.  while ((s = (b+t) >> 1) != b)
  386.        if (mycmp(FromNameList[s]->fromname,fromname)<0) b = s; else t = s;
  387.  return t;
  388. }
  389.  
  390. static int last_fnl_indexnode(fromname)
  391. char *fromname;
  392. {
  393.  register int s, t = fromname_index+1, b = 0;
  394.  
  395.  if (!t) return 0;
  396.  while ((s = (b+t) >> 1) != b)
  397.        if (mycmp(FromNameList[s]->fromname,fromname)>0) t = s; else b = s;
  398.  return b;
  399. }
  400.  
  401. static int fnl_msgclient(msgclient)
  402. aMsgClient *msgclient;
  403. {
  404.  register int t, f, l;
  405.  aMsgClient **index_p;
  406.  
  407.  f = first_fnl_indexnode(msgclient->fromname);
  408.  l = last_fnl_indexnode(msgclient->fromname);
  409.  index_p = FromNameList + f;
  410.  
  411.  for (t = f; t <= l; t++) 
  412.       if (*(index_p++) == msgclient) return(t);
  413.  return 0;
  414.  
  415. static int tnl_msgclient(msgclient)
  416. aMsgClient *msgclient;
  417. {
  418.  register int t, f, l, tname;
  419.  aMsgClient **index_p;
  420.  
  421.  if (msgclient->flags & FLAGS_NAME 
  422.      || !wildcards(msgclient->tonick)) {
  423.      tname = (msgclient->flags & FLAGS_NAME) ? 1 : 0;
  424.      f = first_tnl_indexnode(tname ? msgclient->toname : msgclient->tonick);
  425.      l = last_tnl_indexnode(tname ? msgclient->toname : msgclient->tonick);
  426.      index_p = ToNameList + f;
  427.   } else {
  428.           index_p = WildCardList + 1;
  429.           f = 1; l = wildcard_index;
  430.       }
  431.  for (t = f; t <= l; t++) 
  432.       if (*(index_p++) == msgclient) return(t);
  433.  return 0;
  434.  
  435. static aMsgClient *new(passwd,fromnick,fromname,fromhost,tonick,
  436.                        toname,tohost,flags,timeout,time,message)
  437. char *passwd,*fromnick,*fromname,*fromhost,
  438.      *tonick,*toname,*tohost,*message;
  439. long timeout,time,flags;
  440. {
  441.  register aMsgClient **index_p;
  442.  register int t;
  443.  int allocate,first,last,n;
  444.  aMsgClient *msgclient;
  445.             
  446.  if (number_fromname() > note_msm) return NULL; 
  447.  if (fromname_index == max_fromname-1) {
  448.     max_fromname += REALLOC_SIZE;
  449.     allocate = max_fromname*sizeof(FromNameList)+1;
  450.     FromNameList = (aMsgClient **) MyRealloc((char *)FromNameList,allocate);
  451.   }
  452.  if (wildcard_index == max_wildcards-1) {
  453.     max_wildcards += REALLOC_SIZE;
  454.     allocate = max_wildcards*sizeof(WildCardList)+1;
  455.     WildCardList = (aMsgClient **) MyRealloc((char *)WildCardList,allocate);
  456.   }
  457.  if (toname_index == max_toname-1) {
  458.     max_toname += REALLOC_SIZE;
  459.     allocate = max_toname*sizeof(ToNameList)+1;
  460.     ToNameList = (aMsgClient **) MyRealloc((char *)ToNameList,allocate);
  461.   }
  462.  
  463.  /* Correction if corrupt format */
  464.  if (!(flags & FLAGS_SERVER_GENERATED_NOTICE)
  465.      && !(flags & FLAGS_SERVER_GENERATED_DESTINATION)) flags &= ~FLAGS_NAME; 
  466.  if (!wildcards(toname) && wildcards(tonick)) flags |= FLAGS_NAME; 
  467.  
  468.  msgclient = (aMsgClient *)MyMalloc(sizeof(struct MsgClient));
  469.  DupString(msgclient->passwd,passwd);
  470.  DupString(msgclient->fromnick,fromnick);
  471.  DupString(msgclient->fromname,fromname);
  472.  DupString(msgclient->fromhost,fromhost);
  473.  DupString(msgclient->tonick,tonick);
  474.  DupString(msgclient->toname,toname);
  475.  DupString(msgclient->tohost,tohost);
  476.  DupString(msgclient->message,message);
  477.  msgclient->flags = flags;
  478.  msgclient->timeout = timeout;
  479.  msgclient->time = time;
  480.  if (flags & FLAGS_NAME || !wildcards(tonick)) {
  481.     n = last_tnl_indexnode(flags & FLAGS_NAME ? toname : tonick) + 1;
  482.     index_p = ToNameList+toname_index;
  483.     toname_index++;t = toname_index-n;
  484.     while (t--) {
  485.                   index_p[1] = *index_p; index_p--;
  486.       }
  487.     ToNameList[n] = msgclient;
  488.   } else { 
  489.           wildcard_index++;
  490.           WildCardList[wildcard_index] = msgclient;
  491.      }
  492.  first = first_fnl_indexnode(fromname);
  493.  last = last_fnl_indexnode(fromname);
  494.  if (!(n = first)) n = 1;
  495.  index_p = FromNameList+n;
  496.  while (n <= last && mycmp(msgclient->fromhost,(*index_p)->fromhost)>0) {
  497.         index_p++;n++;
  498.    }
  499.  while (n <= last && mycmp(msgclient->fromnick,(*index_p)->fromnick)>=0){ 
  500.         index_p++;n++;
  501.    }
  502.  index_p = FromNameList+fromname_index;
  503.  fromname_index++;t = fromname_index-n; 
  504.  while (t--) {
  505.                index_p[1] = *index_p; index_p--;
  506.     }
  507.  FromNameList[n] = msgclient;
  508.  changes_to_save = 1;
  509.  msgclient->id = ++m_id;
  510.  return msgclient;
  511. }
  512.  
  513. static void r_code(string,fp)
  514. register char *string;
  515. register FILE *fp;
  516. {
  517.  register int v;
  518.  register char c, *cp = ptr;
  519.  
  520.  do {
  521.       if ((v = getc(fp)) == EOF) {
  522.          exit(-1);       
  523.        }
  524.       c = v;
  525.       *string = c-*cp;
  526.       if (!*++cp) cp = ptr;
  527.   } while (*string++);
  528. }
  529.  
  530. static void w_code(string,fp)
  531. register char *string;
  532. register FILE *fp;
  533. {
  534.  register char *cp = ptr;
  535.  
  536.  do {
  537.       putc((char)(*string+*cp),fp);
  538.       if (!*++cp) cp = ptr;
  539.   } while (*string++);
  540. }
  541.  
  542. static char *ltoa(i)
  543. register long i;
  544. {
  545.  static unsigned char c[20];
  546.  register unsigned char *p = c;
  547.  
  548.   do {
  549.       *p++ = (i&127) + 1;
  550.        i >>= 7;
  551.     } while(i > 0);
  552.     *p = 0;
  553.     return (char *) c;
  554. }
  555.  
  556. static long atol(c)
  557. register unsigned char *c;
  558. {
  559.  register long a = 0;
  560.  register unsigned char *s = c;
  561.  
  562.  while (*s != 0) ++s;
  563.  while (--s >= c) {
  564.         a <<= 7;
  565.         a += *s - 1;
  566.    }
  567.   return a;
  568. }
  569.  
  570. static void init_messages()
  571. {
  572.  FILE *fp,*fopen();
  573.  long timeout,atime,clock,flags;
  574.  int allocate;
  575.  char passwd[20], fromnick[BUF_LEN], fromname[BUF_LEN],
  576.       fromhost[BUF_LEN], tonick[BUF_LEN], toname[BUF_LEN],
  577.       tohost[BUF_LEN], message[MSG_LEN], buf[20];
  578.  
  579.  file_inited = 1;
  580.  max_fromname = max_toname = max_wildcards = REALLOC_SIZE;
  581.  allocate = REALLOC_SIZE*sizeof(FromNameList)+1;
  582.  ToNameList = (aMsgClient **) MyMalloc(allocate);
  583.  FromNameList = (aMsgClient **) MyMalloc(allocate);
  584.  WildCardList = (aMsgClient **) MyMalloc(allocate); 
  585.  note_save_filename_tmp = MyMalloc(strlen(NPATH)+6);
  586.  sprintf(note_save_filename_tmp,"%s.tmp",NPATH);
  587.  time(&clock);old_clock = clock;
  588.  fp = fopen(NPATH,"r");
  589.  if (!fp) return;
  590.  r_code(buf,fp);note_msm = atol(buf);
  591.  r_code(buf,fp);note_mum = atol(buf);
  592.  r_code(buf,fp);note_msw = atol(buf);
  593.  r_code(buf,fp);note_muw = atol(buf);
  594.  r_code(buf,fp);note_mst = atol(buf);
  595.  r_code(buf,fp);note_msf = atol(buf);
  596.  for (;;) {
  597.         r_code(passwd,fp);if (!*passwd) break;
  598.         r_code(fromnick,fp);r_code(fromname,fp);
  599.         r_code(fromhost,fp);r_code(tonick,fp);r_code(toname,fp);
  600.         r_code(tohost,fp);r_code(buf,fp),flags = atol(buf);
  601.         r_code(buf,fp);timeout = atol(buf);r_code(buf,fp);
  602.         atime = atol(buf);r_code(message,fp);
  603.         flags &= ~FLAGS_FROM_REG;
  604.         if (clock > 0 && *toname != DummyChar && *fromname != DummyChar)  
  605.             new(passwd,fromnick,fromname,fromhost,tonick,toname,
  606.                 tohost,flags,timeout,atime,message);
  607.   }
  608.  fclose(fp);
  609. }
  610.  
  611. static int numeric_host(host)
  612. char *host;
  613. {
  614.   while (*host) {
  615.         if (!isdigit(*host) && *host != '.') return 0;
  616.         host++;
  617.    } 
  618.  return 1;
  619. }
  620.  
  621. static int elements_inhost(host)
  622. char *host;
  623. {
  624.  int t = 0;
  625.  
  626.  while (*host) {
  627.        if (*host == '.') t++;
  628.        host++;
  629.     }
  630.  return t;
  631. }
  632.  
  633. static int valid_elements(host)
  634. char *host;
  635. {
  636.  register char *c = host;
  637.  register int t = 0, numeric = 0;
  638.  
  639.  while (*c) {
  640.         if (!isdigit(*c) && *c != '.' && *c != '*' && *c != '?' ) break;
  641.         c++;
  642.    } 
  643.  if (!*c) numeric = 1;
  644.  c = host;
  645.  if (numeric)
  646.      while (*c && *c != '*' && *c != '?') {
  647.             if (*c == '.') t++;
  648.             c++;
  649.       }
  650.   else {
  651.         while (*c++);
  652.         while (c != host && *c != '*' && *c != '?') { 
  653.                if (*c == '.') t++;
  654.                c--;
  655.           }
  656.     } 
  657.  if (!t && *c != '*' && *c != '?') t = 1;
  658.  return t;
  659. }
  660.  
  661. static char *local_host(host)
  662. char *host;
  663. {
  664.  static char buf[BUF_LEN];
  665.  char *buf_p = buf, *host_p;
  666.  int t, e;
  667.  
  668.  e = elements_inhost(host);
  669.  if (e < 2) return host;
  670.  if (!numeric_host(host)) {
  671.      if (!e) return host;
  672.      host_p = host;
  673.      if (e > 2) t = 2; else t = 1;
  674.     while (t--) { 
  675.            while (*host_p && *host_p != '.') {
  676.                   host_p++;buf_p++;
  677.              }
  678.            if (t && *host_p) { 
  679.               host_p++; buf_p++;
  680.         }
  681.       }
  682.      buf[0] = '*';
  683.      strcpy(buf+1, host_p);
  684.   } else {
  685.           host_p = buf;
  686.           strcpy(buf,host);
  687.           while (*host_p) host_p++;    
  688.           t = 2;
  689.           while(t--) {
  690.                while (host_p != buf && *host_p-- != '.'); 
  691.          }
  692.            host_p+=2;
  693.            *host_p++ = '*';
  694.            *host_p = 0;
  695.        }
  696.   return buf;
  697. }
  698.  
  699. static int host_check(host1,host2)
  700. char *host1,*host2;
  701. {
  702.  char buf[BUF_LEN];
  703.  
  704.  if (numeric_host(host1) != numeric_host(host2)) return 0;
  705.  strcpy(buf,local_host(host1));
  706.  if (!mycmp(buf,local_host(host2))) return 1;
  707.  return 0;
  708. }
  709.  
  710. static long timegm(tm)
  711. struct tm *tm;
  712. {
  713.  static int days[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  714.  register long mday = tm->tm_mday-1, mon = tm->tm_mon, year = tm->tm_year-70;
  715.  
  716.  mday+=((year+2) >> 2)+days[mon];
  717.  if (mon < 2 && !((year+2) & 3)) mday--;
  718.  return tm->tm_sec+tm->tm_min*60+tm->tm_hour*3600+mday*86400+year*31536000;
  719. }
  720.  
  721. static long set_date(sptr,time_s)
  722. aClient *sptr;
  723. char *time_s;
  724. {
  725.  struct tm *tm;
  726.  long clock,tm_gmtoff;
  727.  int t,t1,month,date,year;
  728.  char *c = time_s,arg[3][BUF_LEN];
  729.  static char *months[] = {
  730.     "January",    "February",    "March",    "April",
  731.     "May",            "June",            "July",            "August",
  732.     "September",    "October",    "November",    "December"
  733.     }; 
  734.  
  735.  time (&clock);
  736.  tm = localtime(&clock);
  737.  tm_gmtoff = timegm(tm)-clock;
  738.  tm->tm_sec = 0;
  739.  tm->tm_min = 0;
  740.  tm->tm_hour = 0;
  741.  if (*time_s == '-') {
  742.     if (!time_s[1]) return 0;
  743.     return timegm(tm)-tm_gmtoff-3600*24*atoi(time_s+1);
  744.   }
  745.  for (t = 0;t<3;t++) {
  746.       t1 = 0;
  747.       while (*c && *c != '/' && *c != '.' && *c != '-')
  748.              arg[t][t1++] = *c++;
  749.       arg[t][t1] = 0;
  750.       if (*c) c++;
  751.   } 
  752.  
  753.  date = atoi(arg[0]);
  754.  if (*arg[0] && (date<1 || date>31)) {
  755.      sendto_one(sptr,"NOTICE %s :#?# Unknown date",sptr->name);
  756.      return -1;
  757.   }
  758.  month = atoi(arg[1]);
  759.  if (month) month--;
  760.   else for (t = 0;t<12;t++) {
  761.             if (MyEq(arg[1],months[t])) { 
  762.                 month = t;break;
  763.              } 
  764.             month = -1;
  765.         }
  766.  if (*arg[1] && (month<0 || month>11)) {
  767.       sendto_one(sptr,"NOTICE %s :#?# Unknown month",sptr->name);
  768.       return -1; 
  769.   }       
  770.  year = atoi(arg[2]);
  771.  if (*arg[2] && (year<71 || year>99)) {
  772.      sendto_one(sptr,"NOTICE %s :#?# Unknown year",sptr->name);
  773.      return -1;
  774.    }
  775.  tm->tm_mday = date;
  776.  if (*arg[1]) tm->tm_mon = month;
  777.  if (*arg[2]) tm->tm_year = year;
  778.  return timegm(tm)-tm_gmtoff;
  779. }
  780.  
  781. static int local_check(sptr, msgclient, passwd, flags, tonick,
  782.                    toname, tohost, time_l, id)
  783. aClient *sptr;
  784. aMsgClient *msgclient;
  785. char *passwd, *tonick, *toname, *tohost;
  786. long flags,time_l;
  787. int id;
  788. {
  789.  if (msgclient->flags == flags 
  790.      && (!id || id == msgclient->id)
  791.      && !Usermycmp(UserName(sptr),msgclient->fromname)
  792.      && (!mycmp(sptr->name, msgclient->fromnick)
  793.          || wild_fromnick(sptr->name, msgclient))
  794.      && (!time_l || msgclient->time >= time_l 
  795.                     && msgclient->time < time_l+24*3600)
  796.      && !matches(tonick,msgclient->tonick)
  797.      && !matches(toname,msgclient->toname)
  798.      && !matches(tohost,msgclient->tohost)
  799.      && (*msgclient->passwd == '*' && !msgclient->passwd[1]
  800.          || StrEq(passwd,msgclient->passwd))
  801.      &&  host_check(sptr->user->host,msgclient->fromhost)) return 1;
  802.  return 0;
  803. }
  804.  
  805. static int send_flag(flags)
  806. long flags;
  807. {
  808.   if (flags & FLAGS_RETURN_CORRECT_DESTINATION
  809.       || flags & FLAGS_DISPLAY_IF_CORRECT_FOUND
  810.       || flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS
  811.       || flags & FLAGS_DISPLAY_IF_DEST_REGISTER
  812.       || flags & FLAGS_SERVER_GENERATED_DESTINATION
  813.       || flags & FLAGS_NOT_QUEUE_REQUESTS
  814.       || flags & FLAGS_NEWS
  815.       || flags & FLAGS_REPEAT_UNTIL_TIMEOUT
  816.          && !(flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE)) return 0;
  817.   return 1;
  818. }
  819.  
  820. static void display_flags(flags, c, mode)
  821. long flags;
  822. char *c, mode;
  823. {
  824.  char t = 0;
  825.  int send = 0;
  826.  
  827.  if (send_flag(flags)) send = 1;
  828.  if (mode != 'q') {
  829.      if (send) c[t++] = '['; else c[t++] = '<';
  830.   } else c[t++] = '+';
  831.  if (mode != 'q' && (flags & FLAGS_WASOPER)) c[t++] = 'O';
  832.  if (flags & FLAGS_SERVER_GENERATED_DESTINATION) c[t++] = 'H';
  833.  if (flags & FLAGS_ALL_NICK_VALID) c[t++] = 'C';
  834.  if (flags & FLAGS_SERVER_GENERATED_NOTICE) c[t++] = 'G';
  835.  if (flags & FLAGS_DISPLAY_IF_RECEIVED) c[t++] = 'D';
  836.  if (flags & FLAGS_DISPLAY_IF_CORRECT_FOUND) c[t++] = 'L';
  837.  if (flags & FLAGS_NEWS) c[t++] = 'S';
  838.  if (flags & FLAGS_DISPLAY_IF_DEST_REGISTER) c[t++] = 'X';
  839.  if (flags & FLAGS_DISPLAY_CHANNEL_DEST_REGISTER) c[t++] = 'J';
  840.  if (flags & FLAGS_DISPLAY_SERVER_DEST_REGISTER) c[t++] = 'A';
  841.  if (flags & FLAGS_REPEAT_UNTIL_TIMEOUT) c[t++] = 'R';
  842.  if (flags & FLAGS_SIGNOFF_REMOVE) c[t++] = 'M';
  843.  if (flags & FLAGS_NO_NICKCHANGE_SPY) c[t++] = 'U';
  844.  if (flags & FLAGS_NICK_AND_WILDCARD_VALID) c[t++] = 'V';
  845.  if (flags & FLAGS_SEND_ONLY_IF_THIS_SERVER) c[t++] = 'I';
  846.  if (flags & FLAGS_SEND_ONLY_IF_NICK_NOT_NAME) c[t++] = 'Q';
  847.  if (flags & FLAGS_SEND_ONLY_IF_NOT_EXCEPTION) c[t++] = 'E';
  848.  if (flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS) c[t++] = 'K';
  849.  if (flags & FLAGS_SEND_ONLY_IF_SENDER_ON_IRC) c[t++] = 'Y';
  850.  if (flags & FLAGS_NOTICE_RECEIVED_MESSAGE) c[t++] = 'N';
  851.  if (flags & FLAGS_RETURN_CORRECT_DESTINATION) c[t++] = 'F';
  852.  if (flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE) c[t++] = 'B';
  853.  if (flags & FLAGS_REGISTER_NEWNICK) c[t++] = 'T';
  854.  if (flags & FLAGS_SEND_ONLY_IF_DESTINATION_OPER) c[t++] = 'W';
  855.  if (flags & FLAGS_NOT_QUEUE_REQUESTS) c[t++] = 'Z';
  856.  if (t == 1) c[t++] = '-';
  857.  if (mode != 'q') {
  858.      if (send) c[t++] = ']'; else c[t++] = '>';
  859.   }
  860.  c[t] = 0;
  861. }
  862.  
  863. static void remove_msg(msgclient)
  864. aMsgClient *msgclient;
  865. {
  866.  register aMsgClient **index_p;
  867.  register int t;
  868.  int n,allocate;
  869.  
  870.  n = tnl_msgclient(msgclient);
  871.  if (msgclient->flags & FLAGS_NAME 
  872.      || !wildcards(msgclient->tonick)) {
  873.      index_p = ToNameList+n; 
  874.      t = toname_index-n;   
  875.      while (t--) {
  876.                    *index_p = index_p[1]; index_p++;
  877.        }
  878.      ToNameList[toname_index] = 0;
  879.      toname_index--;
  880.   } else { 
  881.           index_p = WildCardList+n; 
  882.           t = wildcard_index-n;
  883.           while (t--) {
  884.                         *index_p = index_p[1]; index_p++;
  885.             }
  886.           WildCardList[wildcard_index] = 0;
  887.           wildcard_index--;
  888.      }
  889.  n = fnl_msgclient(msgclient);
  890.  index_p = FromNameList+n;t = fromname_index-n;
  891.  while (t--) {
  892.                 *index_p = index_p[1]; index_p++;
  893.    }
  894.  FromNameList[fromname_index] = 0;
  895.  fromname_index--;
  896.  MyFree(msgclient->passwd);
  897.  MyFree(msgclient->fromnick);
  898.  MyFree(msgclient->fromname);
  899.  MyFree(msgclient->fromhost);
  900.  MyFree(msgclient->tonick);
  901.  MyFree(msgclient->toname);
  902.  MyFree(msgclient->tohost);
  903.  MyFree(msgclient->message);
  904.  MyFree((char *)msgclient);
  905.  changes_to_save = 1;
  906.  if (max_fromname - fromname_index > REALLOC_SIZE *2) {
  907.     max_fromname -= REALLOC_SIZE; 
  908.     allocate = max_fromname*sizeof(FromNameList)+1;
  909.     FromNameList = (aMsgClient **) MyRealloc((char *)FromNameList,allocate);
  910.   }
  911.  if (max_wildcards - wildcard_index > REALLOC_SIZE * 2) {
  912.     max_wildcards -= REALLOC_SIZE;
  913.     allocate = max_wildcards*sizeof(WildCardList)+1;
  914.     WildCardList = (aMsgClient **) MyRealloc((char *)WildCardList,allocate);
  915.   }
  916.  if (max_toname - toname_index > REALLOC_SIZE * 2) {
  917.     max_toname -= REALLOC_SIZE;
  918.     allocate = max_toname*sizeof(ToNameList)+1;
  919.     ToNameList = (aMsgClient **) MyRealloc((char *)ToNameList,allocate);
  920.   }
  921. }
  922.  
  923. static int KeyFlags(sptr, flags) 
  924. aClient *sptr;
  925. long flags;
  926. {
  927.  int t,last, first_tnl, last_tnl, nick_list = 1;
  928.  long clock;
  929.  aMsgClient **index_p,*msgclient; 
  930.  
  931.  t = first_tnl_indexnode(sptr->name);
  932.  last = last_tnl_indexnode(sptr->name);
  933.  first_tnl = first_tnl_indexnode(UserName(sptr));
  934.  last_tnl = last_tnl_indexnode(UserName(sptr));
  935.  index_p = ToNameList;
  936.  time (&clock);
  937.  while (1) {
  938.      while (last && t <= last) {
  939.         msgclient = index_p[t];
  940.         if (msgclient->flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS
  941.         && msgclient->flags & flags
  942.         && !matches(msgclient->tonick,sptr->name)
  943.         && !matches(msgclient->toname,UserName(sptr))
  944.         && !matches(msgclient->tohost,sptr->user->host)) return 1;
  945.             t++;
  946.     }
  947.      if (index_p == ToNameList) {
  948.          if (nick_list) {
  949.              nick_list = 0; t = first_tnl; last = last_tnl;
  950.       } else {
  951.                    index_p = WildCardList;
  952.                    t = 1; last = wildcard_index;
  953.           }
  954.       } else return 0;
  955.  }
  956. }
  957.  
  958. static int set_flags(sptr, string, flags, mode, type)
  959. aClient *sptr;
  960. char *string, mode, *type;
  961. long *flags;
  962. {
  963.  char *c,on,buf[40],cu;
  964.  int op,uf = 0;
  965.  
  966.  op = IsOperHere(sptr) ? 1:0; 
  967.  for (c = string; *c; c++) {
  968.       if (*c == '+') { 
  969.           on = 1;continue;
  970.        } 
  971.       if (*c == '-') { 
  972.           on = 0;continue;
  973.        } 
  974.       cu = islower(*c)?toupper(*c):*c;
  975.       switch (cu) {
  976.               case 'S': if (on) *flags |= FLAGS_NEWS;
  977.                          else *flags &= ~FLAGS_NEWS;
  978.                         break;             
  979.               case 'R': if (on) *flags |= FLAGS_REPEAT_UNTIL_TIMEOUT;
  980.                          else *flags &= ~FLAGS_REPEAT_UNTIL_TIMEOUT;
  981.                         break;        
  982.               case 'U': if (on) *flags |= FLAGS_NO_NICKCHANGE_SPY;
  983.                          else *flags &= ~FLAGS_NO_NICKCHANGE_SPY;
  984.                         break;             
  985.               case 'V': if (on) *flags |= FLAGS_NICK_AND_WILDCARD_VALID;
  986.                          else *flags &= ~FLAGS_NICK_AND_WILDCARD_VALID;
  987.                         break;             
  988.               case 'I': if (on) *flags |= FLAGS_SEND_ONLY_IF_THIS_SERVER; 
  989.                          else *flags &= ~FLAGS_SEND_ONLY_IF_THIS_SERVER;
  990.                         break;             
  991.               case 'W': if (on) *flags |= FLAGS_SEND_ONLY_IF_DESTINATION_OPER;
  992.                          else *flags &= ~FLAGS_SEND_ONLY_IF_DESTINATION_OPER;
  993.                         break;             
  994.               case 'Q': if (on) *flags |= FLAGS_SEND_ONLY_IF_NICK_NOT_NAME;
  995.                          else *flags &= ~FLAGS_SEND_ONLY_IF_NICK_NOT_NAME;
  996.                         break;             
  997.               case 'E': if (on) *flags |= FLAGS_SEND_ONLY_IF_NOT_EXCEPTION; 
  998.                          else *flags &= ~FLAGS_SEND_ONLY_IF_NOT_EXCEPTION;
  999.                         break;             
  1000.               case 'Y': if (on) *flags |= FLAGS_SEND_ONLY_IF_SENDER_ON_IRC;
  1001.                          else *flags &= FLAGS_SEND_ONLY_IF_SENDER_ON_IRC;
  1002.                         break;             
  1003.               case 'N': if (on) *flags |= FLAGS_NOTICE_RECEIVED_MESSAGE;
  1004.                          else *flags &= ~FLAGS_NOTICE_RECEIVED_MESSAGE;
  1005.                         break;             
  1006.               case 'D': if (on) *flags |= FLAGS_DISPLAY_IF_RECEIVED;
  1007.                          else *flags &= ~FLAGS_DISPLAY_IF_RECEIVED;
  1008.                         break;             
  1009.               case 'F': if (on) *flags |= FLAGS_RETURN_CORRECT_DESTINATION;
  1010.                          else *flags &= ~FLAGS_RETURN_CORRECT_DESTINATION;
  1011.                         break;
  1012.               case 'L': if (on) *flags |= FLAGS_DISPLAY_IF_CORRECT_FOUND;
  1013.                          else *flags &= ~FLAGS_DISPLAY_IF_CORRECT_FOUND;
  1014.                         break;
  1015.               case 'X':  if (on) *flags |= FLAGS_DISPLAY_IF_DEST_REGISTER;
  1016.                           else *flags &= ~FLAGS_DISPLAY_IF_DEST_REGISTER;
  1017.                         break;
  1018.               case 'J':  if (on) *flags |= FLAGS_DISPLAY_CHANNEL_DEST_REGISTER;
  1019.                           else *flags &= ~FLAGS_DISPLAY_CHANNEL_DEST_REGISTER;
  1020.                         break;
  1021.               case 'A':  if (on) *flags |= FLAGS_DISPLAY_SERVER_DEST_REGISTER;
  1022.                           else *flags &= ~FLAGS_DISPLAY_SERVER_DEST_REGISTER;
  1023.                         break;
  1024.               case 'C': if (on) *flags |= FLAGS_ALL_NICK_VALID;
  1025.                          else *flags &= ~FLAGS_ALL_NICK_VALID;
  1026.                         break;
  1027.               case 'M': if (on) *flags |= FLAGS_SIGNOFF_REMOVE;
  1028.                          else *flags &= ~FLAGS_SIGNOFF_REMOVE;
  1029.                         break;
  1030.               case 'T': if (KeyFlags(sptr,FLAGS_REGISTER_NEWNICK) 
  1031.                             || op || mode == 'd' || !on) {
  1032.                             if (on) *flags |= FLAGS_REGISTER_NEWNICK;
  1033.                              else *flags &= ~FLAGS_REGISTER_NEWNICK;
  1034.                          } else buf[uf++] = cu;
  1035.                         break;
  1036.               case 'B': if (KeyFlags(sptr,FLAGS_FIND_CORRECT_DEST_SEND_ONCE)
  1037.                             || op || mode == 'd' || !on) {
  1038.                             if (on) 
  1039.                                *flags |= FLAGS_FIND_CORRECT_DEST_SEND_ONCE;
  1040.                              else *flags &= ~FLAGS_FIND_CORRECT_DEST_SEND_ONCE;
  1041.                          } else buf[uf++] = cu;
  1042.                         break;
  1043.               case 'K': if (op || mode == 'd' || !on) {
  1044.                             if (on) *flags |= FLAGS_KEY_TO_OPEN_OPER_LOCKS;
  1045.                              else *flags &= ~FLAGS_KEY_TO_OPEN_OPER_LOCKS;
  1046.                          } else buf[uf++] = cu;
  1047.                         break;
  1048.               case 'O': if (mode == 'd') {
  1049.                            if (on) *flags |= FLAGS_WASOPER;
  1050.                             else *flags &= ~FLAGS_WASOPER;
  1051.                         } else buf[uf++] = cu;
  1052.                          break;
  1053.               case 'G': if (mode == 'd') {
  1054.                            if (on) *flags |= FLAGS_SERVER_GENERATED_NOTICE;
  1055.                              else *flags &= ~FLAGS_SERVER_GENERATED_NOTICE;
  1056.                  } else buf[uf++] = cu;
  1057.                         break;
  1058.               case 'H': if (mode == 'd') {
  1059.                            if (on) 
  1060.                                *flags |= FLAGS_SERVER_GENERATED_DESTINATION;
  1061.                             else *flags &= ~FLAGS_SERVER_GENERATED_DESTINATION;
  1062.                           } else buf[uf++] = cu;
  1063.                         break;
  1064.               case 'Z': if (KeyFlags(sptr,FLAGS_NOT_QUEUE_REQUESTS)
  1065.                             || op || mode == 'd' || !on) {
  1066.                              if (on) *flags |= FLAGS_NOT_QUEUE_REQUESTS;
  1067.                   else *flags &= ~FLAGS_NOT_QUEUE_REQUESTS;
  1068.                          } else buf[uf++] = cu;
  1069.                          break;  
  1070.               default:  buf[uf++] = cu;
  1071.         } 
  1072.   }
  1073.  buf[uf] = 0;
  1074.  if (uf) {
  1075.      sendto_one(sptr,"NOTICE %s :#?# Unknown flag%s: %s %s",sptr->name,
  1076.                 uf> 1  ? "s" : "",buf,type);
  1077.      return 0;
  1078.   }
  1079.  if (mode == 's') {
  1080.     if (*flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS)
  1081.         sendto_one(sptr,"NOTICE %s :### %s", sptr->name,
  1082.                    "WARNING: Recipient got keys to unlock the secret portal;");
  1083.      else if (*flags & FLAGS_NOT_QUEUE_REQUESTS)
  1084.               sendto_one(sptr,"NOTICE %s :### %s",sptr->name,
  1085.                          "WARNING: Recipient can't queue requests;");
  1086.       else if (*flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE
  1087.                && *flags & FLAGS_REPEAT_UNTIL_TIMEOUT
  1088.                && send_flag(*flags)) 
  1089.                sendto_one(sptr,"NOTICE %s :### %s",sptr->name,
  1090.                          "WARNING: Broadcast message in action;");
  1091.  }
  1092.  return 1;
  1093. }
  1094.  
  1095. static void split(string, nick, name, host)
  1096. char *string, *nick, *name, *host;
  1097. {
  1098.  char *np = string, *fill;
  1099.  
  1100.  *nick = 0; *name = 0; *host = 0;
  1101.  fill = nick;
  1102.  while (*np) { 
  1103.         *fill = *np;
  1104.         if (*np == '!') { 
  1105.            *fill = 0; fill = name;
  1106.      } else if (*np == '@') { 
  1107.                     *fill = 0; fill = host;
  1108.               } else fill++;
  1109.         np++;
  1110.    } 
  1111.  *fill = 0;       
  1112.  if (!*nick) { *nick = '*'; nick[1] = 0; } 
  1113.  if (!*name) { *name = '*'; name[1] = 0; } 
  1114.  if (!*host) { *host = '*'; host[1] = 0; } 
  1115. }
  1116.  
  1117. void save_messages()
  1118. {
  1119.  aMsgClient *msgclient;
  1120.  long clock, gflags = 0;
  1121.  static long t2 = MAX_DAYS_NO_USE_SPY*3600*24;
  1122.  FILE *fp,*fopen();
  1123.  int t = 1;
  1124.  char *c, mbuf[MSG_LEN], dibuf[40];
  1125.  
  1126.  if (!file_inited || !changes_to_save) return;
  1127.  time(&clock);
  1128.  gflags |= FLAGS_WASOPER; gflags |= FLAGS_NAME;
  1129.  gflags |= FLAGS_SERVER_GENERATED_NOTICE;
  1130.  
  1131.  while (fromname_index && t <= fromname_index) {
  1132.         msgclient = FromNameList[t];
  1133.         if (msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER) {
  1134.             *mbuf = '\0';
  1135.             while (!*mbuf) {
  1136.                    strcpy(mbuf, get_msg(msgclient, '2'));
  1137.                    if (!*mbuf) update_spymsg(msgclient);
  1138.           }
  1139.             if (*get_msg(msgclient, 'n') == '-') {
  1140.               if (clock > msgclient->time + t2)
  1141.                   msgclient->timeout = 0; 
  1142.         } else {
  1143.                      if (clock > msgclient->time + t2 + atoi(mbuf))
  1144.                          msgclient->timeout = 0;
  1145.                 } 
  1146.         }       
  1147.        if (clock > msgclient->timeout) {
  1148.            display_flags(msgclient->flags, dibuf, 'q');
  1149.            sprintf(mbuf,"Expired: /Note User -%d %s %s!%s@%s %s", 
  1150.                    (int)((msgclient->timeout - msgclient->time)/3600),
  1151.                    dibuf, msgclient->tonick, msgclient->toname, 
  1152.                    msgclient->tohost, Message(msgclient));
  1153.            c = wild_fromnick(msgclient->fromnick, msgclient);
  1154.            if (msgclient->timeout
  1155.                && !(msgclient->flags & FLAGS_SERVER_GENERATED_NOTICE)
  1156.                && !(msgclient->flags & FLAGS_SERVER_GENERATED_DESTINATION))
  1157.              new(msgclient->passwd,"SERVER","-","-",
  1158.                  c ? c : msgclient->fromnick, msgclient->fromname,
  1159.                  local_host(msgclient->fromhost), gflags,
  1160.                  24*7*3600+clock, clock, mbuf);
  1161.            remove_msg(msgclient); continue;
  1162.         }  
  1163.        t++;
  1164.    }
  1165.  changes_to_save = 0;
  1166.  fp = fopen(note_save_filename_tmp,"w");
  1167.  if (!fp) {
  1168.     sendto_ops("Can't open for write: %s", NPATH);
  1169.     return;
  1170.  }
  1171.  w_code(ltoa((long)note_msm),fp);
  1172.  w_code(ltoa((long)note_mum),fp);
  1173.  w_code(ltoa((long)note_msw),fp);
  1174.  w_code(ltoa((long)note_muw),fp);
  1175.  w_code(ltoa((long)note_mst),fp);
  1176.  w_code(ltoa((long)note_msf),fp);
  1177.  t = 1;
  1178.  while (fromname_index && t <= fromname_index) {
  1179.      msgclient = FromNameList[t];
  1180.      w_code(msgclient->passwd,fp),w_code(msgclient->fromnick,fp);
  1181.      w_code(msgclient->fromname,fp);w_code(msgclient->fromhost,fp);
  1182.      w_code(msgclient->tonick,fp),w_code(msgclient->toname,fp);
  1183.      w_code(msgclient->tohost,fp),
  1184.      w_code(ltoa(msgclient->flags),fp);
  1185.      w_code(ltoa(msgclient->timeout),fp);
  1186.      w_code(ltoa(msgclient->time),fp);
  1187.      w_code(msgclient->message,fp);
  1188.      t++;
  1189.   }
  1190.  w_code("",fp);
  1191.  fclose(fp);
  1192.  fp = fopen(note_save_filename_tmp,"r");
  1193.  if (!fp || getc(fp) == EOF) {
  1194.     sendto_ops("Error writing: %s", note_save_filename_tmp);
  1195.     if (fp) fclose(fp); return; 
  1196.   }
  1197.  fclose (fp);
  1198.  unlink(NPATH);link(note_save_filename_tmp,NPATH);
  1199.  unlink(note_save_filename_tmp);
  1200.  chmod(NPATH, 432);
  1201. }
  1202.  
  1203. static char *flag_send(aptr, sptr, qptr, nick, msgclient, mode, chn)
  1204. aClient *aptr, *sptr, *qptr;
  1205. char *nick, mode, *chn;
  1206. aMsgClient *msgclient;
  1207. {
  1208.  int t, t1, exception;
  1209.  static char ebuf[BUF_LEN];
  1210.  char *c, *message;
  1211.  
  1212.  message = Message(msgclient);
  1213.  
  1214.  if (MyConnect(sptr)) msgclient->flags |= FLAGS_ON_THIS_SERVER;
  1215.      else if (mode != 'e' && mode != 'q') 
  1216.               msgclient->flags &= ~FLAGS_ON_THIS_SERVER;
  1217.  if (!(msgclient->flags & FLAGS_ON_THIS_SERVER) 
  1218.        && msgclient->flags & FLAGS_SEND_ONLY_IF_THIS_SERVER
  1219.      || (msgclient->flags & FLAGS_SEND_ONLY_IF_NICK_NOT_NAME 
  1220.          && mode == 'v' && StrEq(nick,UserName(sptr)))
  1221.      || (!IsOper(sptr) &&
  1222.          msgclient->flags & FLAGS_SEND_ONLY_IF_DESTINATION_OPER)
  1223.      || (mode == 'v' || mode == 'j' || mode == 'l') && qptr == aptr) 
  1224.         return NULLCHAR;
  1225.  
  1226.  if (msgclient->flags & FLAGS_SEND_ONLY_IF_NOT_EXCEPTION) {
  1227.      c = message;
  1228.      for(;;) {
  1229.          exception = 0;t = t1 = 0 ;ebuf[0] = 0;
  1230.          while (*c != '!') {
  1231.                 if (!*c || *c == ' ' || t > BUF_LEN) return message;
  1232.                 ebuf[t++] = *c++;
  1233.            }
  1234.          if (!*c++) return message;
  1235.          t1 += t;ebuf[t] = 0;
  1236.          if (!matches(ebuf,nick)) exception = 1;
  1237.          t=0;ebuf[0] = 0;            
  1238.          while (*c != '@') {
  1239.                 if (!*c || *c == ' ' || t > BUF_LEN) return message;
  1240.                 ebuf[t++] = *c++;
  1241.            }
  1242.          if (!*c++) return message;
  1243.          t1 += t;ebuf[t] = 0;
  1244.          if (matches(ebuf,UserName(sptr))) exception = 0;
  1245.          t=0;ebuf[0] = 0;
  1246.          if (*c == ' ') return message;
  1247.          while (*c && *c != ' ') {
  1248.               if (t > BUF_LEN) return message;
  1249.               ebuf[t++] = *c++;
  1250.            } 
  1251.          if (*c) c++; t1 += t;ebuf[t] = 0; message += t1+2;
  1252.          if (*c) message++;
  1253.          if (exception && !matches(ebuf,sptr->user->host)) return NULLCHAR;
  1254.      }
  1255.    }
  1256.  return message;
  1257. }
  1258.  
  1259. static char *check_flags(aptr, sptr, qptr, nick, newnick, qptr_nick,
  1260.                          msgclient, repeat, gnew, mode, sptr_chn)
  1261. aClient *aptr, *sptr, *qptr;
  1262. aMsgClient *msgclient;
  1263. char *nick, *newnick, *qptr_nick, mode;
  1264. int *repeat, *gnew;
  1265. aChannel *sptr_chn;
  1266. {
  1267.  char *c, mbuf[MSG_LEN], buf[BUF_LEN], ebuf[BUF_LEN], *message, 
  1268.       wmode[2], *spy_channel = NULLCHAR, *spy_server = NULLCHAR;
  1269.  long clock, gflags;
  1270.  int t, t1, t2, last, secret = 1, send = 1, right_tonick = 0, 
  1271.      show_channel = 0, sptr_chn_exits = 0;
  1272.  aMsgClient *fmsgclient;
  1273.  aChannel *chptr;
  1274.  Link *link;
  1275.  
  1276.  if (mode != 'g') {
  1277.     if (!(msgclient->flags & FLAGS_FROM_REG)) qptr = 0;
  1278.      else for (qptr = client; qptr; qptr = qptr->next)
  1279.             if (qptr->user && 
  1280.                 (!mycmp(qptr->name,msgclient->fromnick)
  1281.                 || wild_fromnick(qptr->name, msgclient))
  1282.                 && !Usermycmp(UserName(qptr),msgclient->fromname)
  1283.                 && host_check(qptr->user->host,msgclient->fromhost)) 
  1284.                 break; 
  1285.     if (!qptr) msgclient->flags &= ~FLAGS_FROM_REG;
  1286.   }
  1287.  if (!mycmp(nick, msgclient->tonick)
  1288.      || !mycmp(nick, get_msg(msgclient, 'n'))) right_tonick = 1;
  1289.  if (!sptr->user->channel && !IsInvisible(sptr)) secret = 0;
  1290.  if (secret && !IsInvisible(sptr)) 
  1291.   for (link = sptr->user->channel; link; link = link->next)
  1292.        if (!SecretChannel(link->value.chptr)) secret = 0;
  1293.  if (mode == 'a' || buffer_overload) secret = 1;
  1294.  wmode[1] = 0; *repeat = 0; *gnew = 0; 
  1295.  
  1296.  if (!send_flag(msgclient->flags)) send = 0; 
  1297.  if (mode == 'a' || mode == 'v'
  1298.      || mode == 'c' && !wildcards(msgclient->tonick)
  1299.      || mode == 'g' && (!wild_fromnick(qptr->name, msgclient)
  1300.                         || StrEq(qptr_nick, qptr->name))) {
  1301.      msgclient->flags &= ~FLAGS_NEWNICK_DISPLAYED; 
  1302.      msgclient->flags &= ~FLAGS_PRIVATE_DISPLAYED;
  1303.   }
  1304.  message = flag_send(aptr, sptr, qptr, nick, msgclient, mode, sptr_chn);
  1305.  if (!message
  1306.      || (msgclient->flags & FLAGS_SERVER_GENERATED_NOTICE) && 
  1307.         (mode != 'a' && mode != 'v')
  1308.      || msgclient->flags & FLAGS_SEND_ONLY_IF_SENDER_ON_IRC && !qptr) { 
  1309.     *repeat = 1; return NULLCHAR; 
  1310.   }
  1311.  if ((!secret || right_tonick) 
  1312.      && msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER) {
  1313.      time(&clock);
  1314.      mbuf[0] = 0; buf[0] = SPY_CTRLCHAR; buf[1] = 0;
  1315.      strcat(mbuf, clean_spychar(nick)); strcat(mbuf, buf);
  1316.      strcat(mbuf, clean_spychar(UserName(sptr))); strcat(mbuf, buf);
  1317.      strcat(mbuf, clean_spychar(sptr->user->host)); strcat(mbuf, buf);
  1318.      strcat(mbuf, clean_spychar(sptr->info)); strcat(mbuf, buf);
  1319.      strcat(mbuf, myitoa(clock-msgclient->time)); strcat(mbuf, buf);
  1320.      if (*get_msg(msgclient, '2'))
  1321.         strcat(mbuf, get_msg(msgclient, '2')); 
  1322.       else strcat(mbuf, myitoa(clock-msgclient->time));
  1323.      strcat(mbuf, buf);
  1324.      t = MSG_LEN - strlen(mbuf) - 10;
  1325.      strncat(mbuf, clean_spychar(Message(msgclient)), t);
  1326.      strcat(mbuf, "\0");
  1327.      DupNewString(msgclient->message, mbuf);
  1328.      message = flag_send(aptr, sptr, qptr, nick, msgclient, mode, sptr_chn);
  1329.      changes_to_save = 1;
  1330.    }
  1331.  if (msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER
  1332.      && qptr && qptr != sptr) {
  1333.      time(&clock);
  1334.      t = first_fnl_indexnode(UserName(qptr));
  1335.      last = last_fnl_indexnode(UserName(qptr));
  1336.      while (last && t <= last) {
  1337.             fmsgclient = FromNameList[t];
  1338.             if (fmsgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER
  1339.                 && clock < fmsgclient->timeout
  1340.                 && fmsgclient != msgclient
  1341.                 && (!mycmp(mode == 'g' ? qptr_nick : qptr->name, 
  1342.                     fmsgclient->fromnick)
  1343.                    || wild_fromnick(mode == 'g' ? qptr_nick :qptr->name,
  1344.                                     fmsgclient))
  1345.                 && !Usermycmp(UserName(qptr), fmsgclient->fromname)
  1346.                 && host_check(qptr->user->host, fmsgclient->fromhost)
  1347.                 && !matches(fmsgclient->tonick, nick)
  1348.                 && !matches(fmsgclient->toname, UserName(sptr))
  1349.                 && !matches(fmsgclient->tohost, sptr->user->host)
  1350.                 && flag_send(aptr, sptr, qptr, nick, fmsgclient, 
  1351.                              mode, sptr_chn)) {
  1352.                 t1 = wildcards(fmsgclient->tonick) ? 1 : 0;
  1353.                 t2 = wildcards(msgclient->tonick) ? 1 : 0;
  1354.                 if (!t1 && t2) goto end_this_flag;
  1355.                 if (t1 && !t2) { t++; continue; }
  1356.                 t1 = (fmsgclient->flags & FLAGS_NAME) ? 1 : 0;
  1357.                 t2 = (msgclient->flags & FLAGS_NAME) ? 1 : 0;
  1358.                 if (t1 && !t2) goto end_this_flag;
  1359.                 if (!t1 && t2) { t++; continue; }
  1360.                 if (fnl_msgclient(fmsgclient) < fnl_msgclient(msgclient))
  1361.                     goto end_this_flag;
  1362.           }
  1363.             t++;
  1364.        }
  1365.          mbuf[0] = 0;
  1366.          for (link = sptr->user->channel; link; link = link->next) {
  1367.               chptr = link->value.chptr;
  1368.               if (sptr_chn == chptr) sptr_chn_exits = 1;
  1369.               if (IsMember(qptr, chptr)) {
  1370.                   msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1371.                   if (mode != 'j' && mode != 'l') goto end_this_flag;
  1372.            } else if (ShowChannel(qptr, chptr)) show_channel = 1;
  1373.               if (ShowChannel(qptr, chptr)) {
  1374.                   if (strlen(mbuf)+strlen(chptr->chname) >= MSG_LEN) continue;
  1375.                   if (mbuf[0]) strcat(mbuf, " ");
  1376.               strcat(mbuf, chptr->chname);
  1377.            }       
  1378.         }
  1379.        for (link = qptr->user->channel; link; link = link->next)
  1380.             if (link->value.chptr == sptr_chn) break;
  1381.        if (link || mbuf[0] && sptr_chn_exits && !PubChannel(sptr_chn)) 
  1382.            mbuf[0] = 0;
  1383.         else if (!show_channel) {
  1384.                if (msgclient->flags & FLAGS_PRIVATE_DISPLAYED) mbuf[0] = 0;
  1385.                 else {
  1386.                        strcpy(mbuf, "*Private*");
  1387.                        msgclient->flags |= FLAGS_PRIVATE_DISPLAYED;
  1388.               }
  1389.              } else if (mbuf[0]) msgclient->flags &= ~FLAGS_PRIVATE_DISPLAYED; 
  1390.  
  1391.       if (msgclient->flags & FLAGS_DISPLAY_CHANNEL_DEST_REGISTER
  1392.           && mode != 'v' && mbuf[0]) spy_channel = mbuf;
  1393.       if (msgclient->flags & FLAGS_DISPLAY_SERVER_DEST_REGISTER)
  1394.           spy_server = sptr->user->server;
  1395.       if (spy_channel || spy_server)
  1396.           sprintf(ebuf,"%s%s%s%s%s", spy_channel ? " " : "",
  1397.                   spy_channel ? spy_channel : "",
  1398.                   spy_server ? " (" : "",
  1399.                   spy_server ? spy_server : "",
  1400.                   spy_server ? ")" : "");
  1401.         else ebuf[0] = 0;
  1402.       while (*message == '%') {
  1403.             while (*message && *message != ' ') message++;
  1404.             if (*message) message++;
  1405.     }
  1406.       sprintf(buf,"%s@%s",UserName(sptr),sptr->user->host);
  1407.       switch (mode) {
  1408.         case 'm' :
  1409.         case 'l' :
  1410.      case 'j' : if (!(msgclient->flags & FLAGS_NEWNICK_DISPLAYED)
  1411.                        && !(only_wildcards(msgclient->tonick)
  1412.                        && only_wildcards(msgclient->toname))
  1413.                        && !secret && !right_tonick && !spy_channel) {
  1414.                        sendto_one(qptr, "NOTICE %s :### %s (%s) %s%s %s",
  1415.                                   qptr->name, nick, buf, "signs on",
  1416.                                   ebuf, message);
  1417.                       msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1418.             } else if (spy_channel && 
  1419.                                (!secret || right_tonick)) {
  1420.                                sendto_one(qptr,
  1421.                                           "NOTICE %s :### %s (%s) is on %s",
  1422.                                           qptr->name, nick, buf, spy_channel);
  1423.                                msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1424.             }
  1425.                     break;
  1426.         case 'v' :
  1427.       case 'a' : if (!secret || right_tonick) {
  1428.                        sendto_one(qptr,
  1429.                                   "NOTICE %s :### %s (%s) %s%s %s",
  1430.                                   qptr->name, nick, buf, 
  1431.                                   "signs on", ebuf, message);
  1432.                        msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1433.             }
  1434.                    break;
  1435.     case 'c' : if (!(msgclient->flags & FLAGS_NEWNICK_DISPLAYED)
  1436.                        && !(only_wildcards(msgclient->tonick)
  1437.                             && only_wildcards(msgclient->toname))
  1438.                        && (!secret || right_tonick)) {
  1439.                        sendto_one(qptr,
  1440.                                   "NOTICE %s :### %s (%s) is %s%s %s",
  1441.                         qptr->name, nick, buf,
  1442.                           spy_channel ? "on" : "here",
  1443.                                    ebuf,message);
  1444.                         msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1445.                     }
  1446.                    break;
  1447.         case 's' :
  1448.     case 'g' : if ((!secret || right_tonick) &&
  1449.                       (!(msgclient->flags & FLAGS_NEWNICK_DISPLAYED)
  1450.                         && !(only_wildcards(msgclient->tonick)
  1451.                              && only_wildcards(msgclient->toname)))) {
  1452.                        sendto_one(qptr,
  1453.                                   "NOTICE %s :### %s (%s) is %s%s %s",
  1454.                                qptr->name, nick, buf,
  1455.                                   spy_channel ? "on" : "on IRC now",
  1456.                                   ebuf,message);
  1457.                        msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1458.                     }
  1459.                    break;
  1460.         case 'q' :
  1461.         case 'e' : if (!secret || right_tonick)
  1462.                        sendto_one(qptr,
  1463.                         "NOTICE %s :### %s (%s) %s %s",
  1464.                   qptr->name, nick,
  1465.                       buf,"signs off", message);
  1466.                        break;
  1467.     case 'n' : msgclient->flags &= ~FLAGS_NEWNICK_DISPLAYED;
  1468.                    if (secret) { 
  1469.                        if (right_tonick) 
  1470.                            sendto_one(qptr,
  1471.                                       "NOTICE %s :### %s (%s) %s %s",
  1472.                                       qptr->name, nick, buf,
  1473.                                       "signs off", message);
  1474.                 } else {
  1475.                          if (mycmp(nick, newnick)
  1476.                              && !(msgclient->flags & FLAGS_NO_NICKCHANGE_SPY))
  1477.                             sendto_one(qptr,
  1478.                                        "NOTICE %s :### %s (%s) %s <%s> %s",
  1479.                                        qptr->name, nick, buf, 
  1480.                                        "changed name to", newnick, message);
  1481.                             if (!matches(msgclient->tonick,newnick))
  1482.                                 msgclient->flags |= FLAGS_NEWNICK_DISPLAYED;
  1483.                      }
  1484.  
  1485.       }
  1486.         end_this_flag:;
  1487.  }
  1488.  
  1489.  if (send && !right_tonick && secret
  1490.      && !(msgclient->flags & FLAGS_SERVER_GENERATED_NOTICE)
  1491.      && !(msgclient->flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE)) {
  1492.      if (mode == 'v') nick = msgclient->tonick;
  1493.       else { 
  1494.              *repeat = 1; return NULLCHAR;
  1495.        }
  1496.  }
  1497.  if (mode == 'q' || mode == 'e' || mode == 'n') { 
  1498.      *repeat = 1; return NULLCHAR;
  1499.   }
  1500.  while (mode != 'g' && (msgclient->flags & FLAGS_RETURN_CORRECT_DESTINATION
  1501.         || msgclient->flags & FLAGS_DISPLAY_IF_CORRECT_FOUND)) {
  1502.         if (*message && matches(message, sptr->info) || 
  1503.             secret && !right_tonick) {
  1504.            *repeat = 1; break;
  1505.      }
  1506.         time(&clock); 
  1507.         sprintf(mbuf,"Search for %s!%s@%s (%s): %s!%s@%s (%s)",
  1508.                 msgclient->tonick,msgclient->toname,msgclient->tohost,
  1509.                 *message ? message : "*", nick,
  1510.                 UserName(sptr),sptr->user->host,sptr->info);
  1511.         if (msgclient->flags & FLAGS_DISPLAY_IF_CORRECT_FOUND && qptr) {
  1512.             sendto_one(qptr,"NOTICE %s :### %s",qptr->name,mbuf);
  1513.             break;
  1514.      }
  1515.         t1 = 0; 
  1516.         t = first_tnl_indexnode(msgclient->fromname);
  1517.         last = last_tnl_indexnode(msgclient->fromname);
  1518.         while (last && t <= last) {
  1519.               if (ToNameList[t]->timeout > clock &&
  1520.                   ToNameList[t]->flags & FLAGS_SERVER_GENERATED_NOTICE &&
  1521.                   !Usermycmp(ToNameList[t]->toname, msgclient->fromname) &&
  1522.                   !mycmp(ToNameList[t]->tohost,
  1523.                          local_host(msgclient->fromhost))) {
  1524.                   t1++;
  1525.                   if (!mycmp(Message(ToNameList[t]),mbuf)) {
  1526.                      t1 = -1; break;
  1527.            }
  1528.            }      
  1529.               t++;
  1530.           }  
  1531.         if (t1 < 0) break;
  1532.         if (t1 > 10) {
  1533.             msgclient->timeout = clock-1; 
  1534.             break;
  1535.      }
  1536.         gflags = 0;
  1537.         gflags |= FLAGS_WASOPER;
  1538.         gflags |= FLAGS_NAME;
  1539.         gflags |= FLAGS_SERVER_GENERATED_NOTICE;
  1540.         *gnew = 1;
  1541.         c = wild_fromnick(msgclient->fromnick, msgclient);
  1542.         new(msgclient->passwd,"SERVER_F","-","-",
  1543.             c ? c : msgclient->fromnick, msgclient->fromname,
  1544.             local_host(msgclient->fromhost), gflags, 
  1545.             24*7*3600+clock, clock, mbuf);
  1546.         break;
  1547.   }
  1548. if (msgclient->flags & FLAGS_REPEAT_UNTIL_TIMEOUT) *repeat = 1;
  1549.  
  1550. while (send && qptr != sptr &&
  1551.         (msgclient->flags & FLAGS_NOTICE_RECEIVED_MESSAGE
  1552.          || msgclient->flags & FLAGS_DISPLAY_IF_RECEIVED)) {
  1553.         time(&clock);
  1554.         if (!right_tonick && secret && clock-msgclient->time < 3600*24*7)
  1555.        { *repeat = 1; send = 0; break; }
  1556.         sprintf(buf,"%s (%s@%s) has received note queued %s before delivery.",
  1557.                 nick, UserName(sptr), sptr->user->host,
  1558.                 mytime(msgclient->time));
  1559.         if (msgclient->flags & FLAGS_DISPLAY_IF_RECEIVED && 
  1560.             qptr && (right_tonick || !secret)) {
  1561.            sendto_one(qptr,"NOTICE %s :### %s", qptr->name, buf);
  1562.            break;
  1563.          }
  1564.        gflags = 0;
  1565.        gflags |= FLAGS_WASOPER;
  1566.        gflags |= FLAGS_SERVER_GENERATED_NOTICE;
  1567.        time(&clock);*gnew = 1;
  1568.        c = wild_fromnick(msgclient->fromnick, msgclient);
  1569.        new(msgclient->passwd,"SERVER","-","-",
  1570.            c ? c : msgclient->fromnick, msgclient->fromname,
  1571.            local_host(msgclient->fromhost), gflags,note_mst*24*3600+clock,
  1572.            clock,buf);
  1573.        break;
  1574.     }
  1575.  while (send && msgclient->flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE) {
  1576.         if (mode == 'g') {
  1577.             *repeat = 1; send = 0; break;
  1578.       }
  1579.         t = first_tnl_indexnode(UserName(sptr));
  1580.         last = last_tnl_indexnode(UserName(sptr));
  1581.         while (last && t <= last) {
  1582.              if (ToNameList[t]->flags & FLAGS_SERVER_GENERATED_DESTINATION
  1583.                  && (!mycmp(ToNameList[t]->fromnick,msgclient->fromnick)
  1584.                      || wild_fromnick(ToNameList[t]->fromnick, msgclient))
  1585.                  && !Usermycmp(ToNameList[t]->fromname,msgclient->fromname)
  1586.                  && host_check(ToNameList[t]->fromhost,msgclient->fromhost)
  1587.                  && (!(msgclient->flags & FLAGS_REGISTER_NEWNICK) 
  1588.                      || !mycmp(ToNameList[t]->tonick,nick))
  1589.                  && !Usermycmp(ToNameList[t]->toname,UserName(sptr))
  1590.                  && host_check(ToNameList[t]->tohost,sptr->user->host)) {
  1591.                  send = 0; break;
  1592.              }
  1593.              t++;
  1594.       }
  1595.         if (!send) break;
  1596.         gflags = 0;
  1597.         gflags |= FLAGS_NAME;
  1598.         gflags |= FLAGS_REPEAT_UNTIL_TIMEOUT;
  1599.         gflags |= FLAGS_SERVER_GENERATED_DESTINATION;
  1600.         if (msgclient->flags & FLAGS_ALL_NICK_VALID) 
  1601.          gflags |= FLAGS_ALL_NICK_VALID;
  1602.         if (msgclient->flags & FLAGS_NICK_AND_WILDCARD_VALID) 
  1603.          gflags |= FLAGS_NICK_AND_WILDCARD_VALID;
  1604.         if (msgclient->flags & FLAGS_WASOPER) gflags |= FLAGS_WASOPER;
  1605.         time(&clock); *gnew = 1;
  1606.         new(msgclient->passwd,msgclient->fromnick, msgclient->fromname,
  1607.             msgclient->fromhost,nick,UserName(sptr),
  1608.             sptr->user->host,gflags,msgclient->timeout,clock,"");
  1609.         break;
  1610.    }
  1611.   if (send) return message; 
  1612.    else return NULLCHAR;
  1613. }
  1614.  
  1615. static void check_messages(aptr, sptr, info, mode)
  1616. aClient *sptr, *aptr; /* aptr = who activated */
  1617. void *info;
  1618. char mode;
  1619. {
  1620.  aMsgClient *msgclient, **index_p;
  1621.  char *qptr_nick, dibuf[40], *newnick, *message, *tonick;
  1622.  int last, first_tnl = 0, last_tnl = 0, first_tnil, last_tnil, nick_list = 1,
  1623.      number_matched = 0, t, repeat, gnew;
  1624.  long clock,flags;
  1625.  aClient *qptr = sptr; /* qptr points to active person queued a request */
  1626.  aChannel *sptr_chn = 0;
  1627.  
  1628.  if (!file_inited) init_messages();
  1629.  if (mode == 'm' || mode == 'j' || mode == 'l') {
  1630.      sptr_chn = (aChannel *)info; qptr_nick = sptr->name;
  1631.   } else qptr_nick = (char *)info;
  1632.  tonick = qptr_nick;
  1633.  if (!sptr->user || !*tonick) return;
  1634.  if (mode == 'a' && StrEq(sptr->info,"IRCnote") /* Removed in next release */
  1635.      && StrEq(sptr->name, sptr->info)) {
  1636.          sendto_one(sptr,":%s NOTICE %s : <%s> %s (%d) %s",
  1637.                     me.name, tonick, me.name, VERSION, number_fromname(),
  1638.                     StrEq(ptr,"IRCnote") ? "" : (!*ptr ? "-" : ptr));
  1639.       }
  1640.  time(&clock);
  1641.  if (!fromname_index) return;
  1642.  if (mode != 'j' && mode != 'l') {
  1643.      t = first_fnl_indexnode(UserName(sptr));
  1644.      last = last_fnl_indexnode(UserName(sptr));
  1645.      while (last && t <= last) {
  1646.            msgclient = FromNameList[t];
  1647.            if (!host_check(msgclient->fromhost, sptr->user->host)) {
  1648.                t++; continue;
  1649.             }
  1650.            if (!mycmp(qptr_nick, msgclient->fromnick)
  1651.                || wild_fromnick(qptr_nick, msgclient)) {
  1652.                if (msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER)
  1653.                    update_spymsg(msgclient);
  1654.                if ((mode == 'e' || mode == 'q')
  1655.                    && msgclient->flags & FLAGS_SIGNOFF_REMOVE)
  1656.                    msgclient->timeout = 0;
  1657.         }
  1658.            msgclient->flags |= FLAGS_FROM_REG;
  1659.            t++; 
  1660.         }
  1661.    }
  1662.  if (clock > old_clock+note_msf) {
  1663.     save_messages(); old_clock = clock;
  1664.   }
  1665.  if (mode == 'v') {
  1666.      nick_list = 0; /* Rest done with A flag */
  1667.   }
  1668.  if (mode == 'n') {
  1669.      newnick = tonick;tonick = sptr->name;
  1670.    }
  1671.  if (mode != 'g') {
  1672.      first_tnl = first_tnl_indexnode(UserName(sptr));
  1673.      last_tnl = last_tnl_indexnode(UserName(sptr));
  1674.      first_tnil = first_tnl_indexnode(tonick);
  1675.      last_tnil = last_tnl_indexnode(tonick);
  1676.   }
  1677.  if (mode == 's' || mode == 'g') {
  1678.      t = first_fnl_indexnode(UserName(sptr));
  1679.      last = last_fnl_indexnode(UserName(sptr));
  1680.      index_p = FromNameList;
  1681.      sptr = client; /* Notice new sptr */
  1682.      while (sptr && (!sptr->user || !*sptr->name)) sptr = sptr->next;
  1683.      if (!sptr) return;
  1684.      tonick = sptr->name;
  1685.   } else {
  1686.            if (nick_list) {
  1687.              t = first_tnil; last = last_tnil;
  1688.         } else {
  1689.                      t = first_tnl; last = last_tnl;
  1690.         }
  1691.            index_p = ToNameList;
  1692.       }
  1693.  while(1) {
  1694.     while (last && t <= last) {
  1695.            msgclient = index_p[t];
  1696.            if (msgclient->timeout < clock
  1697.                || index_p == WildCardList  
  1698.                   && (send_flag(msgclient->flags) 
  1699.                       || msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER)
  1700.                   && ((msgclient->flags & FLAGS_WASOPER 
  1701.                        && !valid_elements(msgclient->tohost))
  1702.                        || !(msgclient->flags & FLAGS_WASOPER)
  1703.                           && matches(local_host(sptr->user->host), 
  1704.                                      msgclient->tohost))) {
  1705.               t++; continue;
  1706.         }
  1707.            gnew = 0; repeat=1;
  1708.            if (!(msgclient->flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS)
  1709.                && !(msgclient->flags & FLAGS_SERVER_GENERATED_DESTINATION)
  1710.                && (index_p != ToNameList 
  1711.                    || (!nick_list && msgclient->flags & FLAGS_NAME)
  1712.                    || (nick_list && !(msgclient->flags & FLAGS_NAME)))
  1713.                && !matches(msgclient->tonick, tonick)
  1714.                && !matches(msgclient->toname, UserName(sptr))
  1715.                && !matches(msgclient->tohost, sptr->user->host)
  1716.                && (mode != 's' && mode != 'g'
  1717.                    || (wild_fromnick(qptr_nick, msgclient)
  1718.                        || !mycmp(qptr_nick, msgclient->fromnick))
  1719.                        && host_check(msgclient->fromhost, 
  1720.                                      qptr->user->host))) {
  1721.                message = check_flags(aptr, sptr, qptr, tonick, newnick,
  1722.                                      qptr_nick, msgclient, &repeat, 
  1723.                                      &gnew, mode, sptr_chn);
  1724.                if (message) {
  1725.                    flags = msgclient->flags;
  1726.                    display_flags(flags, dibuf, '-');
  1727.                    if (flags & FLAGS_SERVER_GENERATED_NOTICE)
  1728.                        sendto_one(sptr,"NOTICE %s :/%s/ %s",
  1729.                                   tonick, mytime(msgclient->time), message);
  1730.                    else sendto_one(sptr,
  1731.                                    "NOTICE %s :Note from %s!%s@%s /%s/ %s %s",
  1732.                                     tonick, msgclient->fromnick, 
  1733.                                     msgclient->fromname, msgclient->fromhost, 
  1734.                                     mytime(msgclient->time), dibuf, message);
  1735.                    }
  1736.                if (!(msgclient->flags & FLAGS_NAME)) number_matched++;
  1737.          }
  1738.            if (!repeat) msgclient->timeout = 0;
  1739.            if (gnew) {
  1740.                if (mode != 'g') {
  1741.                   first_tnl = first_tnl_indexnode(UserName(sptr));
  1742.                   last_tnl = last_tnl_indexnode(UserName(sptr));
  1743.                   first_tnil = first_tnl_indexnode(tonick);
  1744.                   last_tnil = last_tnl_indexnode(tonick);
  1745.         }
  1746.                if (mode == 's' || mode == 'g') {
  1747.                   t = fnl_msgclient(msgclient);
  1748.                   last = last_fnl_indexnode(UserName(qptr));
  1749.         } else {
  1750.                          if (index_p == ToNameList) {
  1751.                              t = tnl_msgclient(msgclient);
  1752.                              if (nick_list) last = last_tnil; 
  1753.                               else last = last_tnl;
  1754.                         }
  1755.             }
  1756.             } 
  1757.            if (repeat && (mode == 's' || mode =='g')) {
  1758.                sptr = sptr->next;
  1759.                while (sptr && (!sptr->user || !*sptr->name)) sptr = sptr->next;
  1760.                 if (!sptr || number_matched) {
  1761.                     number_matched = 0; sptr = client; 
  1762.                     while (sptr && (!sptr->user || !*sptr->name))
  1763.                            sptr = sptr->next;
  1764.                     if (!sptr) return;
  1765.                     tonick = sptr->name; t++; continue;
  1766.          }
  1767.                tonick = sptr->name;
  1768.             } else t++;
  1769.      }
  1770.      if (mode == 's' || mode == 'g') return;
  1771.      if (index_p == ToNameList) {
  1772.          if (nick_list) {
  1773.              if (mode == 'a' || mode == 'q') break;
  1774.              nick_list = 0; t = first_tnl; last = last_tnl;
  1775.       } else {
  1776.                   index_p = WildCardList;
  1777.                   t = 1; last = wildcard_index;
  1778.          }
  1779.       } else {
  1780.                if (mode == 'n') {
  1781.                    mode = 'c'; tonick = newnick;
  1782.                    first_tnil = first_tnl_indexnode(tonick);
  1783.                    last_tnil = last_tnl_indexnode(tonick);
  1784.                    t = first_tnil; last = last_tnil;
  1785.                    nick_list = 1; index_p = ToNameList;
  1786.             } else break;
  1787.      }
  1788.   }
  1789.   if (mode == 'c' || mode == 'a') 
  1790.      check_messages(sptr, sptr, tonick, 'g');
  1791. }
  1792.  
  1793. static int check_lastclient(sptr, mode, clock, sptr_chn)
  1794. aClient *sptr;
  1795. char mode;
  1796. long clock;
  1797. aChannel *sptr_chn;
  1798. {
  1799.   static aClient *client_list[LAST_CLIENTS + 1];
  1800.   static long max_last_client = -1, time_list[LAST_CLIENTS + 1], reset = 0;
  1801.   static long last_check_time = 0;
  1802.   static char mode_list[LAST_CLIENTS + 1];
  1803.   static aChannel *chn_list[LAST_CLIENTS + 1];
  1804.   register aClient *sptr_exist, *last_client;
  1805.   register int t = 0, new = -1, multi_buffered = 0, ret = 1;
  1806.   register long longest_time = 0;
  1807.   register char b_mode;
  1808.  
  1809.  if (!reset) { 
  1810.     for (t = 0; t < LAST_CLIENTS; t++) client_list[t] = 0;
  1811.     reset = 1;
  1812.   }
  1813.  if (mode == 'j' || mode == 'e' || mode == 'l')
  1814.      for (t = 0; t <= max_last_client; t++) {
  1815.          if (client_list[t] != sptr) continue;
  1816.          b_mode = mode_list[t];
  1817.          if (mode == 'e') {
  1818.             if (b_mode == 'v' && ret) {
  1819.                 ret = 0; check_messages(sptr, sptr, sptr->name, 'q');
  1820.          }
  1821.             client_list[t] = 0;
  1822.       } else if (b_mode == 'j' || b_mode == 'l') {
  1823.                      multi_buffered = 1;
  1824.                      time_list[t] = clock;
  1825.                      mode_list[t] = mode;
  1826.              chn_list[t] = 0;
  1827.                      break;
  1828.               }
  1829.        }
  1830.   if (!multi_buffered && 
  1831.       (mode == 'a' || mode == 'j' || mode == 'l' || mode == 'o'))
  1832.       for (t = 0; t < LAST_CLIENTS; t++) {
  1833.            if (!client_list[t]) { new = t; break; }
  1834.            if (time_list[t] > longest_time) {
  1835.                longest_time = time_list[t];
  1836.                new = t;
  1837.         }
  1838.        }
  1839.  if (mode != 'a' && mode != 'j' && mode != 'l' || last_check_time != clock) {
  1840.      last_check_time = clock;
  1841.      for (t = 0; t <= max_last_client; t++)
  1842.          if (client_list[t] && 
  1843.              (clock - time_list[t] > SECONDS_WAITFOR_MODE 
  1844.              || (client_list[t] == sptr && mode != 'j' 
  1845.                  && mode != 'l' && mode != 'o') 
  1846.              || t == new)) {
  1847.              last_client = client_list[t];
  1848.              for (sptr_exist=client;sptr_exist;sptr_exist = sptr_exist->next)
  1849.              if (sptr_exist == last_client) break;
  1850.              if (sptr_exist) {
  1851.                 if (t == new) buffer_overload = 1;
  1852.                 if (mode_list[t] == 'j' || mode_list[t] == 'l')
  1853.                  check_messages(sptr ? sptr : client_list[t], client_list[t], 
  1854.                                 chn_list[t], mode_list[t]);
  1855.                  else check_messages(sptr ? sptr : client_list[t], 
  1856.                                      client_list[t], client_list[t]->name, 
  1857.                                      mode_list[t]);
  1858.                  buffer_overload = 0;
  1859.               }
  1860.              client_list[t] = 0;
  1861.              if (max_last_client == t)
  1862.               while (max_last_client > -1 && !client_list[max_last_client]) 
  1863.                 max_last_client--;
  1864.          }
  1865.    }
  1866.  if (new != -1) {
  1867.     client_list[new] = sptr; 
  1868.     time_list[new] = clock;
  1869.     chn_list[new] = sptr_chn;
  1870.     if (mode == 'a') mode_list[new] = 'v';
  1871.      else mode_list[new] = mode; 
  1872.     if (new > max_last_client) max_last_client = new;
  1873.   }
  1874.  return ret;
  1875. }
  1876.  
  1877. void check_command(info, command, par1, par2, par3)
  1878. void *info;
  1879. char *command, *par1, *par2, *par3;
  1880. {
  1881.  char *arg, *c, mode, nick[BUF_LEN]; 
  1882.  static char last = 0, last_command[BUF_LEN], last_nick[BUF_LEN], 
  1883.         last_chn[BUF_LEN], last_mode = 0, last_modes[BUF_LEN];
  1884.  int from_secret = 0, on = -1;
  1885.  long *delay, clock, last_call = 0, source;
  1886.  Link *link;
  1887.  aChannel *chptr = 0;
  1888.  aClient *sptr;
  1889.  
  1890.  time (&clock);
  1891.  if (!last) {
  1892.      last_command[0] = 0; last_nick[0] = 0; 
  1893.      last_modes[0] = 0, last_chn[0] = 0; last = 1;
  1894.   }
  1895.  if (!command) {
  1896.         delay = (long *) info;
  1897.         if (*delay > SECONDS_WAITFOR_MODE) *delay = SECONDS_WAITFOR_MODE;
  1898.         if (clock - last_call < SECONDS_WAITFOR_MODE) return;
  1899.         last_call = clock;
  1900.         check_lastclient((aClient *)0, (char)'-', clock, (aChannel *)0);
  1901.         return;
  1902.   } 
  1903.  source = (long) info;
  1904.  arg = split_string(command, 2, 1);
  1905.  if (StrEq(arg, "USER")) mode = 'a'; else
  1906.  if (StrEq(arg, "NICK")) mode = 'n'; else
  1907.  if (StrEq(arg, "JOIN")) mode = 'j'; else
  1908.  if (StrEq(arg, "MODE")) mode = 'm'; else
  1909.  if (StrEq(arg, "QUIT")) mode = 'e'; else
  1910.  if (StrEq(arg, "PART") || StrEq(arg, "KICK")) mode = 'l'; else 
  1911.  if (StrEq(arg, "KILL")) {
  1912.      par1 = par2; /* Who kills before who's killed here... */
  1913.      mode = 'e';
  1914.  } else return;
  1915.  strcpy(nick, par1);
  1916.  if ((c = (char *)index(nick, '!')) != NULL) *c = '\0';
  1917.  if ((c = (char *)index(nick, '[')) != NULL) *c = '\0';
  1918.  if (mode == 'm' && (c = (char *)index(command, '+')) != NULL) par3 = c;
  1919.  if (mode == 'm' && (c = (char *)index(command, '-')) != NULL) par3 = c;
  1920.  if (mode == 'm' && (c = (char *)index(command, 'c')) != NULL) return;
  1921.  if (mode == 'j' && (c = (char *)index(command, '0')) != NULL) par2 = c+1;
  1922.  
  1923.  if (last_mode == mode && StrEq(last_nick, nick)) {
  1924.      if (mode == 'm') {
  1925.          if (StrEq(last_modes, par3)) return;
  1926.       }  else if (mode == 'j' || mode == 'l') {
  1927.                   if (StrEq(last_chn, par2)) return;
  1928.                } else return;
  1929.   }
  1930.  if (mode == 'm') strncpyzt(last_modes, par3, BUF_LEN-1);
  1931.  if (mode == 'j' || mode == 'l') strncpyzt(last_chn, par2, BUF_LEN-1);
  1932.  strncpyzt(last_command, command, BUF_LEN-1); 
  1933.  strncpyzt(last_nick, nick, BUF_LEN-1); 
  1934.  last_mode = mode;
  1935.  
  1936.  if (mode == 'm' && *par3 == '+' && par3[1] == 'o') mode = 'o';
  1937.  sptr = find_person(nick, (aClient *)NULL);
  1938.  if (!sptr) for (sptr = client; sptr; sptr = sptr->next)
  1939.                  if (StrEq(sptr->name, nick)) break;
  1940.  if (!sptr || !sptr->user || !IsRegisteredUser(sptr)) return;
  1941.  if (mode != 'j' && mode != 'l' && mode != 'm') {
  1942.      if (check_lastclient(sptr, mode, clock, chptr) && mode != 'o')
  1943.          check_messages(sptr, sptr, mode == 'n' ? par2 : sptr->name, mode);
  1944.      return;
  1945.   }
  1946.  for (link = sptr->user->channel; link; link = link->next)
  1947.       if (link->value.chptr && 
  1948.           StrEq(par2, link->value.chptr->chname)) break;
  1949.  if (link) chptr = link->value.chptr;
  1950.  for (link = sptr->user->channel; link; link = link->next)
  1951.       if (link->value.chptr != chptr && PubChannel(link->value.chptr)) break;
  1952.  if (chptr && link && !PubChannel(chptr)) return;  
  1953.  if (mode != 'm') {
  1954.      check_lastclient(sptr, mode, clock, chptr);
  1955.      return;
  1956.   }
  1957.  for (c = par3; *c; c++) {
  1958.       if (*c == '+') { 
  1959.           on = 1;continue;
  1960.        } 
  1961.       if (*c == '-') { 
  1962.           on = 0;continue;
  1963.        } 
  1964.       if (!on && (!chptr && *c == 'i' || *c == 'p' || *c == 's')
  1965.           && (!chptr || PubChannel(chptr))) from_secret = 1;
  1966.    }
  1967.  if (!from_secret) return;
  1968.  if (chptr)
  1969.      for (link = chptr->members; link; link = link->next) {
  1970.           check_lastclient(link->value.cptr, mode, clock, chptr);
  1971.           check_messages(link->value.cptr, link->value.cptr, chptr, mode);
  1972.       }
  1973.   else {
  1974.          check_lastclient(sptr, mode, clock, chptr);
  1975.          check_messages(sptr, sptr, chptr, mode);
  1976.     }
  1977. }
  1978.  
  1979. static void msg_remove(sptr, passwd, flag_s, id_s, name, time_s)
  1980. aClient *sptr;
  1981. char *passwd, *flag_s, *id_s, *name, *time_s;
  1982. {
  1983.  aMsgClient *msgclient;
  1984.  int removed = 0, t, last, id;
  1985.  long clock, flags = 0, time_l;
  1986.  char dibuf[40], tonick[BUF_LEN], toname[BUF_LEN], tohost[BUF_LEN];
  1987.  
  1988.  if (!set_flags(sptr,flag_s, &flags,'d',"")) return;
  1989.  if (!*time_s) time_l = 0; 
  1990.   else { 
  1991.         time_l = set_date(sptr,time_s);
  1992.         if (time_l < 0) return;
  1993.     }
  1994.  split(name, tonick, toname, tohost);
  1995.  if (id_s) id = atoi(id_s); else id = 0;
  1996.  t = first_fnl_indexnode(UserName(sptr));
  1997.  last = last_fnl_indexnode(UserName(sptr));
  1998.  time (&clock);
  1999.  while (last && t <= last) {
  2000.        msgclient = FromNameList[t]; flags = msgclient->flags;
  2001.         if (clock > msgclient->timeout) { t++; continue; }
  2002.         set_flags(sptr, flag_s, &flags, 'd',"");
  2003.         if (local_check(sptr,msgclient,passwd,flags,
  2004.                         tonick,toname,tohost,time_l,id)) {
  2005.             display_flags(msgclient->flags, dibuf, '-'),
  2006.             sendto_one(sptr,"NOTICE %s :### Removed -> %s %s (%s@%s)",
  2007.                        sptr->name,dibuf,msgclient->tonick,
  2008.                        msgclient->toname,msgclient->tohost);
  2009.             remove_msg(msgclient); last--; removed++;
  2010.  
  2011.         } else t++;
  2012.    }
  2013.  if (!removed) 
  2014.   sendto_one(sptr,"NOTICE %s :#?# No such request(s) found", sptr->name);
  2015. }
  2016.  
  2017. static void msg_save(sptr)
  2018. aClient *sptr;
  2019. {
  2020.  if (!changes_to_save) {
  2021.      sendto_one(sptr,"NOTICE %s :### No changes to save",sptr->name);
  2022.      return;
  2023.  }
  2024.  if (IsOperHere(sptr)) {
  2025.     save_messages();
  2026.     sendto_one(sptr,"NOTICE %s :### Requests are now saved",sptr->name);
  2027.   } else
  2028.       sendto_one(sptr,"NOTICE %s :### Oops! All requests lost...",sptr->name);
  2029. }
  2030.  
  2031. static void setvar(sptr,msg,l,value)
  2032. aClient *sptr;
  2033. int *msg,l;
  2034. char *value;
  2035. {
  2036.  int max;
  2037.  static char *message[] = {
  2038.              "Max server messages:",
  2039.              "I don't think that this is a good idea...",
  2040.              "Max server messages are set to:",
  2041.              "Max server messages with wildcards:",
  2042.              "Too many wildcards makes life too hard...",
  2043.              "Max server messages with wildcards are set to:",
  2044.              "Max user messages:",
  2045.              "Too cheeky fingers on keyboard error...",
  2046.              "Max user messages are set to:",
  2047.              "Max user messages with wildcards:",
  2048.              "Give me $$$, and I may fix your problem...",
  2049.              "Max user messages with wildcards are set to:",
  2050.              "Max server days:",
  2051.              "Can't remember that long time...",
  2052.              "Max server days are set to:",
  2053.              "Note save frequency:",
  2054.              "Save frequency may not be like that...",
  2055.              "Note save frequency is set to:" 
  2056.           };
  2057.  
  2058.  if (*value) {
  2059.     max = atoi(value);
  2060.     if (!IsOperHere(sptr))
  2061.         sendto_one(sptr,"NOTICE %s :### %s",sptr->name,message[l+1]);
  2062.      else { 
  2063.            if (!max && (msg == ¬e_mst || msg == ¬e_msf)) max = 1;
  2064.            *msg = max;if (msg == ¬e_msf) *msg *= 60;
  2065.            sendto_one(sptr,"NOTICE %s :### %s %d",sptr->name,message[l+2],max);
  2066.            changes_to_save = 1;
  2067.        }
  2068.  } else {
  2069.          max = *msg; if (msg == ¬e_msf) max /= 60;
  2070.          sendto_one(sptr,"NOTICE %s :### %s %d",sptr->name,message[l],max);
  2071.      }
  2072. }
  2073.  
  2074. static void msg_stats(sptr, arg, value)
  2075. aClient *sptr;
  2076. char *arg, *value;
  2077. {
  2078.  long clock;
  2079.  char buf[BUF_LEN], *fromhost = NULLCHAR, *fromnick, *fromname;
  2080.  int tonick_wildcards = 0,toname_wildcards = 0,tohost_wildcards = 0,any = 0,
  2081.      nicks = 0,names = 0,hosts = 0,t = 1,last = fromname_index,flag_notice = 0,
  2082.      flag_destination = 0, all_wildcards = 0;
  2083.  aMsgClient *msgclient;
  2084.  
  2085.  if (*arg) {
  2086.      if (!mycmp(arg,"MSM")) setvar(sptr,¬e_msm,0,value); else 
  2087.      if (!mycmp(arg,"MSW")) setvar(sptr,¬e_msw,3,value); else
  2088.      if (!mycmp(arg,"MUM")) setvar(sptr,¬e_mum,6,value); else
  2089.      if (!mycmp(arg,"MUW")) setvar(sptr,¬e_muw,9,value); else
  2090.      if (!mycmp(arg,"MST")) setvar(sptr,¬e_mst,12,value); else
  2091.      if (!mycmp(arg,"MSF")) setvar(sptr,¬e_msf,15,value); else
  2092.      if (MyEq(arg,"USED")) {
  2093.          time(&clock);
  2094.          while (last && t <= last) {
  2095.                 msgclient = FromNameList[t];
  2096.                 if (clock > msgclient->timeout) { t++; continue; }
  2097.                 any++;
  2098.                 if (msgclient->flags & FLAGS_SERVER_GENERATED_DESTINATION)
  2099.                     flag_destination++; else
  2100.                 if (msgclient->flags & FLAGS_SERVER_GENERATED_NOTICE)
  2101.                     flag_notice++; else
  2102.                 if (IsOperHere(sptr) || Key(sptr))
  2103.                     if (!fromhost || 
  2104.                         !host_check(msgclient->fromhost,fromhost)) {
  2105.                         nicks++;names++;hosts++;
  2106.                         fromhost = msgclient->fromhost;
  2107.                         fromname = msgclient->fromname;
  2108.                         fromnick = msgclient->fromnick;
  2109.                      } else if (Usermycmp(msgclient->fromname,fromname)) {
  2110.                                 nicks++;names++;
  2111.                                 fromname = msgclient->fromname;
  2112.                                 fromnick = msgclient->fromnick;
  2113.                              } else if (mycmp(msgclient->fromnick,fromnick)) {
  2114.                                         nicks++;
  2115.                                         fromnick = msgclient->fromnick;
  2116.                                } 
  2117.                 if (wildcards(msgclient->tonick) && 
  2118.                     wildcards(msgclient->toname)) all_wildcards++;
  2119.                 if (wildcards(msgclient->tonick))
  2120.                     tonick_wildcards++;
  2121.                 if (wildcards(msgclient->toname))
  2122.                     toname_wildcards++;
  2123.                 if (wildcards(msgclient->tohost))
  2124.                     tohost_wildcards++;
  2125.                 t++;
  2126.         }
  2127.         if (!any) 
  2128.              sendto_one(sptr,"NOTICE %s :#?# No request(s) found",sptr->name);
  2129.                 else {
  2130.                      if (IsOperHere(sptr) || Key(sptr)) {
  2131.                          sprintf(buf,"%s%d %s%d %s%d %s (%s%d %s%d %s%d %s%d)",
  2132.                                  "Nicks:",nicks,"Names:",names,
  2133.                                  "Hosts:",hosts,"W.cards",
  2134.                                  "Nicks:",tonick_wildcards,
  2135.                                  "Names:",toname_wildcards,
  2136.                                  "Hosts:",tohost_wildcards,
  2137.                                  "All:",all_wildcards);
  2138.                          sendto_one(sptr,"NOTICE %s :### %s",sptr->name,buf);
  2139.               }
  2140.                       sprintf(buf,"%s %s%d / %s%d",
  2141.                               "Server generated",
  2142.                               "G-notice: ",flag_notice,
  2143.                               "H-header: ",flag_destination);
  2144.                       sendto_one(sptr,"NOTICE %s :### %s",sptr->name,buf);
  2145.          }
  2146.      } else if (!mycmp(arg,"RESET")) {
  2147.                 if (!IsOperHere(sptr)) 
  2148.                     sendto_one(sptr,"NOTICE %s :### %s",sptr->name,
  2149.                                "Wrong button - try another next time...");
  2150.                  else {
  2151.                        note_mst = NOTE_MAXSERVER_TIME,
  2152.                        note_mum = NOTE_MAXUSER_MESSAGES,
  2153.                        note_msm = NOTE_MAXSERVER_MESSAGES,
  2154.                        note_msw = NOTE_MAXSERVER_WILDCARDS,
  2155.                        note_muw = NOTE_MAXUSER_WILDCARDS;
  2156.                        note_msf = NOTE_SAVE_FREQUENCY*60;
  2157.                        sendto_one(sptr,"NOTICE %s :### %s",
  2158.                                   sptr->name,"Stats have been reset");
  2159.                        changes_to_save = 1;
  2160.            }
  2161.         }
  2162.   } else {
  2163.       t = number_fromname();
  2164.       sprintf(buf,"%s%d /%s%d /%s%d /%s%d /%s%d /%s%d /%s%d",
  2165.               "QUEUE:",t,
  2166.               "MSM:",note_msm,
  2167.               "MSW:",note_msw,
  2168.               "MUM:",note_mum,
  2169.               "MUW:",note_muw,
  2170.               "MST:",note_mst,
  2171.               "MSF:",note_msf/60);
  2172.         sendto_one(sptr,"NOTICE %s :### %s",sptr->name,buf);
  2173.     }
  2174. }
  2175.  
  2176. static int msg_send(sptr, silent, passwd, flag_s, timeout_s, name, message)
  2177. aClient *sptr;
  2178. int silent;
  2179. char *passwd, *flag_s, *timeout_s, *name, *message;
  2180. {
  2181.  aMsgClient **index_p, *msgclient;
  2182.  int sent_wild = 0, sent = 0, nick_list = 1,
  2183.      first_tnl, last_tnl, t, first, last, join = 0;
  2184.  long clock, timeout, flags = 0;
  2185.  char buf[BUF_LEN], dibuf[40], *empty_char = "", tonick[BUF_LEN], 
  2186.       toname[BUF_LEN], tohost[BUF_LEN], *msg;
  2187.  
  2188.  time (&clock);
  2189.  t = first_tnl_indexnode(sptr->name);
  2190.  last = last_tnl_indexnode(sptr->name);
  2191.  first_tnl = first_tnl_indexnode(UserName(sptr));
  2192.  last_tnl = last_tnl_indexnode(UserName(sptr));
  2193.  index_p = ToNameList;
  2194.  time (&clock);
  2195.  while (1) {
  2196.      while (last && t <= last) {
  2197.           msgclient = index_p[t];
  2198.         if (clock > msgclient->timeout) { t++; continue; }
  2199.             msg = flag_send((aClient *)0, sptr, (aClient *)0 , sptr->name, 
  2200.                   msgclient, '-', NULLCHAR);
  2201.             if (msg && msgclient->flags & FLAGS_NOT_QUEUE_REQUESTS
  2202.             && !(msgclient->flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS)
  2203.              && !matches(msgclient->tonick,sptr->name) 
  2204.              && !matches(msgclient->toname,UserName(sptr))
  2205.             && !matches(msgclient->tohost,sptr->user->host)) {
  2206.         sendto_one(sptr,"NOTICE %s :### %s (%s@%s) %s %s",sptr->name,
  2207.                msgclient->fromnick,msgclient->fromname,
  2208.                msgclient->fromhost,
  2209.                            "doesn't allow you to queue requests:", msg);
  2210.         return -1;
  2211.         }
  2212.             t++;
  2213.     }
  2214.      if (index_p == ToNameList) {
  2215.          if (nick_list) {
  2216.              nick_list = 0; t = first_tnl; last = last_tnl;
  2217.           } else {
  2218.                    index_p = WildCardList;
  2219.                    t = 1; last = wildcard_index;
  2220.               }
  2221.  
  2222.       } else break;
  2223.  }
  2224.  if (number_fromname() >= note_msm 
  2225.      && !IsOperHere(sptr) && !Key(sptr)) {
  2226.      if (!note_msm || !note_mum)
  2227.          sendto_one(sptr,
  2228.                     "NOTICE %s :#?# The notesystem is closed for no-operators",
  2229.                     sptr->name);
  2230.       else sendto_one(sptr,"NOTICE %s :#?# No more than %d request%s %s",
  2231.                       sptr->name, note_msm, note_msm < 2 ? "" : "s",
  2232.                       "allowed in the server");
  2233.      return -1;
  2234.   }
  2235.  if (clock > old_clock+note_msf) {
  2236.     save_messages();old_clock = clock;
  2237.   }
  2238.  if (!set_flags(sptr,flag_s,&flags,'s',"")) return -1;
  2239.  split(name, tonick, toname, tohost);
  2240.  if (IsOper(sptr)) flags |= FLAGS_WASOPER;
  2241.  if (*timeout_s == '+') timeout = atoi(timeout_s + 1) * 24;
  2242.   else if (*timeout_s == '-') timeout = atoi(timeout_s + 1);
  2243.  if (timeout > note_mst*24 && !(flags & FLAGS_WASOPER) && !Key(sptr)) {
  2244.     sendto_one(sptr,"NOTICE %s :#?# Max time allowed is %d day%s",
  2245.                sptr->name,note_mst,note_mst > 1 ? "s" : "");
  2246.     return -1;
  2247.   }
  2248.  if (!message) {
  2249.     if (!send_flag(flags)) message = empty_char; 
  2250.      else {
  2251.            sendto_one(sptr,"NOTICE %s :#?# No message specified",sptr->name);
  2252.            return -1;
  2253.        }
  2254.   }
  2255.  if (*toname == DummyChar) {
  2256.      sendto_one(sptr,
  2257.                 "NOTICE %s :#?# Please skip that first character in username",
  2258.                 sptr->name);
  2259.      return -1;
  2260.   }
  2261.  first = first_fnl_indexnode(UserName(sptr));
  2262.  last = last_fnl_indexnode(UserName(sptr));
  2263.  t = first;
  2264.  while (last && t <= last) {
  2265.         msgclient = FromNameList[t];
  2266.         if (clock > msgclient->timeout) { t++; continue; }
  2267.         if (!mycmp(sptr->name, msgclient->fromnick)
  2268.             && !Usermycmp(UserName(sptr), msgclient->fromname)
  2269.             && host_check(sptr->user->host, msgclient->fromhost)
  2270.             && StrEq(msgclient->tonick, tonick)
  2271.             && StrEq(msgclient->toname, toname)
  2272.             && StrEq(msgclient->tohost, tohost)
  2273.             && StrEq(msgclient->passwd, passwd)
  2274.             && StrEq(Message(msgclient), clean_spychar(message))
  2275.             && msgclient->flags == (msgclient->flags | flags)) {
  2276.             msgclient->timeout = timeout*3600+clock;
  2277.             join = 1;
  2278.       }
  2279.         t++;
  2280.     }
  2281.   if (!join && !(flags & FLAGS_WASOPER) && !Key(sptr)) {
  2282.      time(&clock); t = first;
  2283.      while (last && t <= last) {
  2284.          if (!Usermycmp(UserName(sptr),FromNameList[t]->fromname)) {
  2285.              if (host_check(sptr->user->host,FromNameList[t]->fromhost)) {
  2286.                  sent++;
  2287.                  if (wildcards(FromNameList[t]->tonick)
  2288.                      && wildcards(FromNameList[t]->toname))
  2289.                     sent_wild++;  
  2290.               }
  2291.                  
  2292.           }
  2293.          t++;
  2294.        }
  2295.      if (sent >= note_mum) {
  2296.         sendto_one(sptr,"NOTICE %s :#?# No more than %d request%s %s",
  2297.                    sptr->name,note_mum,note_mum < 2?"":"s",
  2298.                    "for each user allowed in the server");
  2299.         return -1;
  2300.       }
  2301.      while (wildcards(tonick) && wildcards(toname)) {
  2302.             if (!note_msw || !note_muw)
  2303.                 sendto_one(sptr,
  2304.                           "NOTICE %s :#?# No-operators are not allowed %s",
  2305.                           sptr->name,
  2306.                           "to specify nick and username with wildcards");
  2307.             else if (wildcard_index >= note_msw) 
  2308.                      sendto_one(sptr,"NOTICE %s :#?# No more than %d req. %s",
  2309.                                 sptr->name, note_msw,
  2310.                                 "with nick and username w.cards allowed.");
  2311.             else if (sent_wild >= note_muw) 
  2312.                      sendto_one(sptr,"NOTICE %s :#?# No more than %d %s %s",
  2313.                                 sptr->name, note_muw, 
  2314.                                 note_muw < 2 ? "request ":" requests",
  2315.                                 "with nick and username w.cards allowed.");
  2316.           else break;
  2317.           return -1;
  2318.      }
  2319.    }
  2320.  while ((send_flag(flags) || flags & FLAGS_DISPLAY_IF_DEST_REGISTER) &&
  2321.        wildcards(tonick) && wildcards(toname)) { 
  2322.        if ((flags & FLAGS_WASOPER || Key(sptr)) && !valid_elements(tohost))
  2323.           sendto_one(sptr, 
  2324.                      "NOTICE %s :#?# This matches more than one country.",
  2325.                      sptr->name);
  2326.         else if (!(flags & FLAGS_WASOPER) && !Key(sptr) &&
  2327.                  matches(local_host(sptr->user->host), tohost))
  2328.                  sendto_one(sptr, "NOTICE %s :#?# %s must be a local host.",
  2329.                             sptr->name, local_host(sptr->user->host));
  2330.           else break; 
  2331.        return -1;
  2332.   }
  2333.  if (!join) {
  2334.      time(&clock);
  2335.      flags |= FLAGS_FROM_REG;
  2336.      msgclient = new(passwd,sptr->name, UserName(sptr),  
  2337.                      sptr->user->host, tonick, toname, tohost, flags, 
  2338.                      timeout*3600+clock, clock, clean_spychar(message));
  2339.      if (flags & FLAGS_DISPLAY_IF_DEST_REGISTER) update_spymsg(msgclient);
  2340.   }
  2341.  display_flags(flags, dibuf, '-');
  2342.  sprintf(buf, "%s %s %s!%s@%s for %s",
  2343.          join ? "Joined..." : "Queued...",dibuf, 
  2344.          tonick, toname, tohost, relative_time(timeout*3600));
  2345.  if (!silent) {
  2346.     sendto_one(sptr,"NOTICE %s :### %s",sptr->name, buf);
  2347.     if (send_flag(flags)) check_messages(sptr, sptr, sptr->name, 's');
  2348.   }
  2349.  if (join) return 0; else return 1;
  2350. }
  2351.  
  2352. static void msg_news(sptr, silent, passwd, flag_s, timeout_s, name, message)
  2353. aClient *sptr;
  2354. int silent;
  2355. char *passwd, *flag_s, *timeout_s, *name, *message;
  2356. {
  2357.  aMsgClient *msgclient;
  2358.  long clock;
  2359.  int joined = 0, queued = 0, ret, t = 1, msg_len;
  2360.  char *c, tonick[BUF_LEN], toname[BUF_LEN], tohost[BUF_LEN], 
  2361.       anyname[BUF_LEN], buf[MSG_LEN];
  2362.  
  2363.  split(name, tonick, toname, tohost);
  2364.  if (MyEq("ADMIN.", tonick) && !IsOper(sptr) && !KeyFlags(sptr, FLAGS_NEWS)) {
  2365.      sendto_one(sptr,
  2366.                 "NOTICE %s :#?# No privileges for admin group.", 
  2367.                 sptr->name);
  2368.      return;
  2369.   }
  2370.  time (&clock);
  2371.  sprintf(buf, "[News:%s] ", tonick); msg_len = MSG_LEN-strlen(buf)-1;
  2372.  strncat(buf, message, msg_len); strcat(flag_s, "-RS");
  2373.  while (fromname_index && t <= fromname_index) {
  2374.         msgclient = FromNameList[t];
  2375.         if (!Usermycmp(UserName(sptr), msgclient->fromname)
  2376.             && (!mycmp(sptr->name, msgclient->fromnick)
  2377.                 || wild_fromnick(sptr->name, msgclient)
  2378.             &&  host_check(sptr->user->host,msgclient->fromhost))) {
  2379.         t++; continue;
  2380.      }
  2381.         if (clock < msgclient->timeout
  2382.             && !(msgclient->flags & FLAGS_SERVER_GENERATED_NOTICE)
  2383.             && !(msgclient->flags & FLAGS_SERVER_GENERATED_DESTINATION)  
  2384.             && (msgclient->flags & FLAGS_NEWS
  2385.                 && !matches(msgclient->tonick, tonick)
  2386.                 && !matches(msgclient->toname, UserName(sptr))
  2387.                 && !matches(msgclient->tohost, sptr->user->host)
  2388.                 && (!matches(toname, msgclient->tonick)
  2389.                     || matches(toname, tonick)
  2390.                        && !mycmp(msgclient->tonick, tonick))      
  2391.                 && (!*Message(msgclient)
  2392.                     || !matches(Message(msgclient), message))
  2393.                 || !mycmp(tonick, "admin.users"))
  2394.             && !matches(tohost, msgclient->fromhost)
  2395.             && !(msgclient->flags & FLAGS_KEY_TO_OPEN_OPER_LOCKS)) {
  2396.             c = wild_fromnick(msgclient->fromnick, msgclient);            
  2397.             sprintf(anyname, "%s!%s@%s", 
  2398.                     c ? c : msgclient->fromnick, msgclient->fromname, 
  2399.                     local_host(msgclient->fromhost));
  2400.             ret = msg_send(sptr, 1, passwd, flag_s, 
  2401.                            timeout_s, anyname, buf);
  2402.             if (!ret) joined++;
  2403.              else if (ret < 0) return;
  2404.                else { 
  2405.                      queued++;
  2406.                      t = fnl_msgclient(msgclient);
  2407.          }
  2408.      }
  2409.        t++;
  2410.    }
  2411.  strcpy(buf, "user");
  2412.  if (queued > 1) strcat(buf, "s"); 
  2413.  if (joined) { 
  2414.     strcat(buf, ", ");
  2415.     strcat(buf, myitoa(joined)); strcat(buf, " joined");
  2416.   } 
  2417.  sendto_one(sptr,"NOTICE %s :### News to %d %s", sptr->name, queued, buf);
  2418. }
  2419.  
  2420. static void msg_list(sptr, arg, passwd, flag_s, id_s, name, time_s)
  2421. aClient *sptr;
  2422. char *arg, *passwd, *flag_s, *id_s, *name, *time_s;
  2423. {
  2424.  aMsgClient *msgclient;
  2425.  int number = 0, t, last, ls = 0, count = 0, 
  2426.      found = 0, log = 0, id, id_count = 0;
  2427.  long clock, flags = 0, time_l, time_queued;
  2428.  char tonick[BUF_LEN], toname[BUF_LEN], tohost[BUF_LEN],
  2429.       *message, buf[BUF_LEN], dibuf[40], mbuf[MSG_LEN], 
  2430.       *dots = "...", *wildcard = "*";
  2431.  
  2432.  if (MyEq(arg,"ls")) ls = 1; else
  2433.  if (MyEq(arg,"count")) count = 1; else
  2434.  if (MyEq(arg,"log")) log = 1; else
  2435.  if (MyEq(arg,"llog")) log = 3;
  2436.   else {
  2437.          sendto_one(sptr,"NOTICE %s :#?# No such option: %s",sptr->name,arg); 
  2438.          return;
  2439.     }
  2440.  if (!*name && !id_s && !*flag_s) {
  2441.               if (log) log++;
  2442.               if (ls) ls++;
  2443.               name = wildcard;
  2444.   }
  2445.  if (!set_flags(sptr,flag_s, &flags,'d',"")) return;
  2446.  if (!*time_s) time_l = 0; 
  2447.   else { 
  2448.         time_l = set_date(sptr,time_s);
  2449.         if (time_l < 0) return;
  2450.     }
  2451.  split(name, tonick, toname, tohost);
  2452.  if (id_s) id = atoi(id_s); else id = 0;
  2453.  t = first_fnl_indexnode(UserName(sptr));
  2454.  last = last_fnl_indexnode(UserName(sptr));
  2455.  time(&clock); 
  2456.  while (last && t <= last) {
  2457.         msgclient = FromNameList[t];
  2458.     msgclient->id = ++id_count;
  2459.         flags = msgclient->flags;
  2460.         if (clock > msgclient->timeout) { t++; continue; }
  2461.         set_flags(sptr,flag_s,&flags,'d',"");
  2462.         if (local_check(sptr,msgclient,passwd,flags,
  2463.                            tonick,toname,tohost,time_l,id)) {
  2464.             message = Message(msgclient); number++;
  2465.             if (ls == 2 && *message) message = dots;
  2466.             display_flags(msgclient->flags, dibuf, '-');
  2467.             if (log) { 
  2468.                 if (!(msgclient->flags & FLAGS_DISPLAY_IF_DEST_REGISTER))
  2469.                     { t++ ; continue; }
  2470.                 strcpy(mbuf, get_msg(msgclient, 'n'));
  2471.                 if (*mbuf == '-') *mbuf = '\0';
  2472.                 if (*mbuf) { 
  2473.                    strcat(mbuf, "!");
  2474.                    strcat(mbuf, get_msg(msgclient, 'u')); strcat(mbuf, "@");
  2475.                    strcat(mbuf, get_msg(msgclient, 'h')); 
  2476.                    time_queued = atoi(get_msg(msgclient, '1'))+msgclient->time;
  2477.                  }
  2478.                 if (log == 1 || log == 3) {            
  2479.                    found++;
  2480.                    if (*mbuf) {
  2481.                       strcat(mbuf, " (");
  2482.                       strcat(mbuf, get_msg(msgclient, 'r')); strcat(mbuf, ")");
  2483.                     } else {
  2484.                              time_queued = clock;
  2485.                              strcpy(mbuf, "<No matches yet>");
  2486.                 }
  2487.                    sendto_one(sptr,"NOTICE %s :### %s: %s!%s@%s => %s", 
  2488.                               sptr->name, log == 1 ? mytime(time_queued) :
  2489.                               myctime(time_queued),
  2490.                               msgclient->tonick, msgclient->toname, 
  2491.                               msgclient->tohost, mbuf); 
  2492.              } else if (*mbuf) {
  2493.                             found++;
  2494.                             sendto_one(sptr,"NOTICE %s :### %s: %s", 
  2495.                                        sptr->name, 
  2496.                                        log == 2 ? mytime(time_queued) :
  2497.                                        myctime(time_queued), mbuf); 
  2498.                 }
  2499.           } else 
  2500.                  if (!count) {
  2501.                     found++;
  2502.                     sprintf(buf,"for %s", 
  2503.                            relative_time(msgclient->timeout-clock));
  2504.                     sendto_one(sptr,"NOTICE %s :#%d %s %s (%s@%s) %s: %s",
  2505.                               sptr->name, msgclient->id, dibuf,
  2506.                               msgclient->tonick, msgclient->toname,
  2507.                               msgclient->tohost, buf, message);
  2508.          }
  2509.      }
  2510.        t++;
  2511.      }
  2512.  if (count) sendto_one(sptr,"NOTICE %s :### %s %s (%s@%s): %d",
  2513.                        sptr->name,"Number of requests to",
  2514.                        tonick ? tonick : "*", toname ? toname:"*",
  2515.                        tohost ? tohost : "*", number);
  2516.   else if (!found) sendto_one(sptr,"NOTICE %s :#?# No such %s", sptr->name,
  2517.                               log ? "log(s)" : "request(s) found");
  2518. }
  2519.  
  2520. static void msg_flag(sptr, passwd, flag_s, id_s, name, newflag_s)
  2521. aClient *sptr;
  2522. char *passwd, *flag_s, *id_s, *name, *newflag_s;
  2523. {
  2524.  aMsgClient *msgclient;
  2525.  int flagged = 0, t, last, id;
  2526.  long clock, flags = 0;
  2527.  char tonick[BUF_LEN], toname[BUF_LEN], tohost[BUF_LEN],
  2528.       dibuf1[40], dibuf2[40];
  2529.  
  2530.  if (!*newflag_s) {
  2531.      sendto_one(sptr,"NOTICE %s :#?# No flag changes specified",sptr->name);
  2532.      return;
  2533.   }
  2534.  if (!set_flags(sptr, flag_s, &flags,'d',"in matches flag")) return;
  2535.  if (!set_flags(sptr, newflag_s, &flags,'c',"in flag changes")) return;
  2536.  split(name, tonick, toname, tohost);
  2537.  if (id_s) id = atoi(id_s); else id = 0;
  2538.  t = first_fnl_indexnode(UserName(sptr));
  2539.  last = last_fnl_indexnode(UserName(sptr));
  2540.  time(&clock);
  2541.  while (last && t <= last) {
  2542.        msgclient = FromNameList[t];flags = msgclient->flags;
  2543.         if (clock > msgclient->timeout) { t++; continue; }
  2544.         set_flags(sptr,flag_s,&flags,'d',"");
  2545.         if (local_check(sptr,msgclient,passwd,flags,
  2546.                         tonick,toname,tohost,0,id)) {
  2547.             flags = msgclient->flags; display_flags(flags, dibuf1, '-');
  2548.             set_flags(sptr,newflag_s,&msgclient->flags,'s',"");
  2549.             display_flags(msgclient->flags, dibuf2, '-');
  2550.             if (flags == msgclient->flags) 
  2551.                 sendto_one(sptr,"NOTICE %s :### %s -> %s %s (%s@%s)",
  2552.                            sptr->name, "No flag change for",
  2553.                            dibuf1, msgclient->tonick,
  2554.                            msgclient->toname,msgclient->tohost);
  2555.              else                                        
  2556.                 sendto_one(sptr,"NOTICE %s :### %s -> %s %s (%s@%s) to %s",
  2557.                           sptr->name,"Flag change",dibuf1,msgclient->tonick,
  2558.                           msgclient->toname, msgclient->tohost, dibuf2);
  2559.            flagged++;
  2560.         } 
  2561.        t++;
  2562.    }
  2563.  if (!flagged) 
  2564.   sendto_one(sptr,"NOTICE %s :#?# No such request(s) found",sptr->name);
  2565. }
  2566.  
  2567. static void msg_sent(sptr, arg, name, time_s, delete)
  2568. aClient *sptr;
  2569. char *arg, *name, *time_s, *delete;
  2570. {
  2571.  aMsgClient *msgclient,*next_msgclient;
  2572.  char fromnick[BUF_LEN], fromname[BUF_LEN], fromhost[BUF_LEN]; 
  2573.  int number = 0, t, t1, last, nick = 0, count = 0, users = 0;
  2574.  long clock,time_l;
  2575.  
  2576.  if (!*arg) nick = 1; else
  2577.   if (MyEq(arg,"COUNT")) count = 1; else
  2578.    if (MyEq(arg,"USERS")) users = 1; else
  2579.    if (!MyEq(arg,"NAME")) {
  2580.        sendto_one(sptr,"NOTICE %s :#?# No such option: %s",sptr->name, arg); 
  2581.        return;
  2582.   }
  2583.  if (users) {
  2584.     if (!IsOperHere(sptr)) {
  2585.         sendto_one(sptr,"NOTICE %s :### %s",sptr->name,
  2586.                    "A dragon is guarding the names...");
  2587.         return;
  2588.      }
  2589.     if (!*time_s) time_l = 0; 
  2590.      else { 
  2591.             time_l = set_date(sptr,time_s);
  2592.             if (time_l < 0) return;
  2593.        }
  2594.     split(name, fromnick, fromname, fromhost); 
  2595.     time(&clock);
  2596.     for (t = 1; t <= fromname_index; t++) {
  2597.          msgclient = FromNameList[t]; t1 = t;
  2598.          do next_msgclient = t1 < fromname_index ? FromNameList[++t1] : 0;
  2599.           while (next_msgclient && next_msgclient->timeout <= clock);
  2600.          if (msgclient->timeout > clock
  2601.              && (!time_l || msgclient->time >= time_l 
  2602.                  && msgclient->time < time_l+24*3600)
  2603.              && (!matches(fromnick,msgclient->fromnick))
  2604.              && (!matches(fromname,msgclient->fromname))
  2605.              && (!matches(fromhost,msgclient->fromhost))
  2606.              && (!*delete || !mycmp(delete,"RM")
  2607.                  || !mycmp(delete,"RMBF") &&
  2608.                     (msgclient->flags & FLAGS_RETURN_CORRECT_DESTINATION ||
  2609.                      msgclient->flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE))) {
  2610.              if (*delete || !next_msgclient
  2611.                  || mycmp(next_msgclient->fromnick,msgclient->fromnick)
  2612.                  || mycmp(next_msgclient->fromname,msgclient->fromname)     
  2613.                  || !(host_check(next_msgclient->fromhost,
  2614.                                  msgclient->fromhost))) {
  2615.                   sendto_one(sptr,"NOTICE %s :### %s[%d] %s (%s@%s) @%s",
  2616.                              sptr->name,
  2617.                              *delete ? "Removing -> " : "", 
  2618.                              *delete ? 1 : count+1,
  2619.                              msgclient->fromnick,msgclient->fromname,
  2620.                              local_host(msgclient->fromhost),
  2621.                              msgclient->fromhost);
  2622.                     if (*delete) msgclient->timeout = clock-1;
  2623.                  count = 0; number = 1;
  2624.          } else count++;
  2625.      }
  2626.      }
  2627.     if (!number) 
  2628.      sendto_one(sptr, "NOTICE %s :#?# No request(s) from such user(s) found",
  2629.                 sptr->name);
  2630.   return;
  2631.  }
  2632.  t = first_fnl_indexnode(UserName(sptr));
  2633.  last = last_fnl_indexnode(UserName(sptr));
  2634.  time (&clock);
  2635.  while (last && t <= last) {
  2636.         msgclient = FromNameList[t];
  2637.         if (clock > msgclient->timeout) { t++; continue; }
  2638.         if (!Usermycmp(UserName(sptr),msgclient->fromname)
  2639.             && (!nick || !mycmp(sptr->name,msgclient->fromnick))) {
  2640.             if (host_check(sptr->user->host,msgclient->fromhost)) { 
  2641.                 if (!count) 
  2642.                     sendto_one(sptr,"NOTICE %s :### Queued %s from host %s",
  2643.                                sptr->name, mytime(msgclient->time),
  2644.                                msgclient->fromhost);
  2645.                 number++;
  2646.              }
  2647.          }
  2648.        t++;
  2649.     }
  2650.  if (!number) 
  2651.   sendto_one(sptr,"NOTICE %s :#?# No such request(s) found",sptr->name);
  2652.   else if (count) sendto_one(sptr,"NOTICE %s :### %s %d",sptr->name,
  2653.                              "Number of requests queued:",number);
  2654. }
  2655.  
  2656. static int name_len_error(sptr, name)
  2657. aClient *sptr;
  2658. char *name;
  2659. {
  2660.  if (strlen(name) >= BUF_LEN) {
  2661.     sendto_one(sptr,
  2662.                "NOTICE %s :#?# Nick!name@host can't be longer than %d chars",
  2663.                sptr->name, BUF_LEN-1);
  2664.     return 1;
  2665.   }
  2666.  return 0;
  2667. }
  2668.  
  2669. static int flag_len_error(sptr, flag_s)
  2670. aClient *sptr;
  2671. char *flag_s;
  2672. {
  2673.  if (strlen(flag_s) >= BUF_LEN) {
  2674.     sendto_one(sptr,"NOTICE %s :#?# Flag string can't be longer than %d chars",
  2675.                sptr->name,BUF_LEN-1);
  2676.     return 1;
  2677.   }
  2678.  return 0;
  2679. }
  2680.  
  2681. static int alias_send(sptr, option, flags, msg, timeout)
  2682. aClient *sptr;
  2683. char *option, **flags, **msg, **timeout;
  2684. {
  2685.  static char flag_s[BUF_LEN+10], *deft = "+31",
  2686.         *waitfor_message = "[Waiting]";
  2687.  
  2688.  if (MyEq(option,"SEND")) {
  2689.      sprintf(flag_s,"+D%s", *flags);
  2690.      if (!*timeout) *timeout = deft; 
  2691.   } else
  2692.  if (MyEq(option,"NEWS")) {
  2693.      sprintf(flag_s,"+RS%s", *flags);
  2694.      if (!*timeout) *timeout = deft; 
  2695.   } else
  2696.  if (MyEq(option,"WAITFOR")) { 
  2697.      sprintf(flag_s,"+YD%s", *flags); 
  2698.      if (!*msg) *msg = waitfor_message; 
  2699.   } else 
  2700.  if (MyEq(option,"SPY")) sprintf(flag_s,"+RX%s", *flags); else
  2701.  if (MyEq(option,"FIND")) sprintf(flag_s,"+FR%s", *flags); else
  2702.  if (MyEq(option,"KEY")) sprintf(flag_s,"+KR%s", *flags); else
  2703.  if (MyEq(option,"WALL")) sprintf(flag_s,"+BR%s", *flags); else
  2704.  if (MyEq(option,"WALLOPS")) sprintf(flag_s,"+BRW%s", *flags); else
  2705.  if (MyEq(option,"DENY")) sprintf(flag_s,"+RZ%s", *flags); else
  2706.   return 0;
  2707.  *flags = flag_s;
  2708.  return 1;
  2709. }
  2710.  
  2711. static void antiwall(sptr)
  2712. aClient *sptr;
  2713. {
  2714.  int t = 1, wall = 0;
  2715.  aMsgClient *msgclient;
  2716.  long gflags = 0, clock;
  2717.  char buf[MSG_LEN], *c;
  2718.  
  2719.  time (&clock);
  2720.  if (!IsOper(sptr)) { 
  2721.      sendto_one(sptr,"NOTICE %s :#?# Only ghosts may travel through walls...", 
  2722.                sptr->name);
  2723.      return;
  2724.   }
  2725.  while (fromname_index && t <= fromname_index) {
  2726.         msgclient = FromNameList[t];
  2727.         if (msgclient->flags & FLAGS_FIND_CORRECT_DEST_SEND_ONCE 
  2728.             && !matches(msgclient->tonick, sptr->name)
  2729.             && !matches(msgclient->toname, UserName(sptr))
  2730.             && !matches(msgclient->tohost, sptr->user->host)
  2731.             && flag_send((aClient *)0, sptr, (aClient *)0, sptr->name, 
  2732.                          msgclient, '-', NULLCHAR)) {
  2733.             msgclient->flags &= ~FLAGS_FIND_CORRECT_DEST_SEND_ONCE;
  2734.             sendto_one(sptr,
  2735.                        "NOTICE %s :### Note wall to %s!%s@%s deactivated.", 
  2736.                        sptr->name, msgclient->tonick, msgclient->toname, 
  2737.                        msgclient->tohost);
  2738.             sprintf(buf,"%s (%s@%s) has deactivated your Note Wall...",
  2739.                     sptr->name,UserName(sptr),sptr->user->host);
  2740.             c = wild_fromnick(msgclient->fromnick, msgclient);
  2741.             gflags |= FLAGS_WASOPER;
  2742.             gflags |= FLAGS_SERVER_GENERATED_NOTICE;
  2743.             new(msgclient->passwd,"SERVER","-","-",
  2744.                 c ? c : msgclient->fromnick, msgclient->fromname,
  2745.                 local_host(msgclient->fromhost), gflags, 
  2746.                            note_mst*24*3600+clock, clock, buf);
  2747.             wall = 1;
  2748.      }
  2749.         t++;
  2750.     }
  2751.  if (!wall) { 
  2752.      sendto_one(sptr,"NOTICE %s :#?# Hunting for ghost walls?", 
  2753.                 sptr->name);
  2754.      return;
  2755.   }
  2756. }
  2757.  
  2758. int m_note(cptr, sptr, parc, parv)
  2759. aClient *cptr, *sptr;
  2760. int parc;
  2761. char *parv[];
  2762. {
  2763.  char *option, *arg, *timeout = NULLCHAR, *passwd = NULLCHAR, *param,  
  2764.       *id = NULLCHAR, *flags = NULLCHAR, *name = NULLCHAR, *msg = NULLCHAR,
  2765.       *wildcard = "*", *c, *c2, *default_timeout = "+1", *deft = "+31";
  2766.  static char buf1[BUF_LEN], buf2[BUF_LEN], buf3[BUF_LEN],
  2767.         buf4[BUF_LEN], msg_buf[MSG_LEN], passwd_buf[BUF_LEN], 
  2768.         timeout_buf[BUF_LEN], option_buf[BUF_LEN], 
  2769.         id_buf[BUF_LEN], flags_buf[BUF_LEN + 3];
  2770.  int t, silent = 0, remote = 0;
  2771.  aClient *acptr;
  2772.  
  2773.  if (!file_inited) init_messages();
  2774.  if (parc < 2) {
  2775.     sendto_one(sptr,"NOTICE %s :#?# No option specified.", sptr->name); 
  2776.     return -1;
  2777.   }
  2778.  param = parv[1];
  2779.  if (parc > 1 && !myncmp(param,"service ",8)) {
  2780.      if (!IsOperHere(sptr)) {
  2781.          sendto_one(sptr,"NOTICE %s :### %s",sptr->name,
  2782.                    "Beyond your power poor soul...");
  2783.          return 0;
  2784.       }
  2785.      sptr = find_person(split_string(param, 2, 1), (aClient *)0);
  2786.      if (!sptr) return 0;
  2787.      t = 0; 
  2788.      while (*param && t < 2) {
  2789.             if (*param == ' ') t++;
  2790.             param++;
  2791.        }                 
  2792.      if (!*param) parc = 0;
  2793.   }  else {
  2794.            c = split_string(param, 1, 1); c2 = c;
  2795.            while (*c2 && *c2 != '.') c2++;
  2796.            if (*c2) {
  2797.                if (wildcards(c))
  2798.                    for (t = 0; t <= highest_fd; t++) {
  2799.                        if (!(acptr = local[t])) continue;
  2800.                        if (IsServer(acptr) && acptr != cptr) 
  2801.                           sendto_one(acptr, ":%s NOTE %s", sptr->name, param);
  2802.             }
  2803.                  else for (acptr = client; acptr; acptr = acptr->next)
  2804.                           if (IsServer(acptr) && acptr != cptr
  2805.                               && !mycmp(c, acptr->name)) {
  2806.                       sendto_one(acptr, 
  2807.                                         ":%s NOTE %s", sptr->name, param);
  2808.                               break;
  2809.                }
  2810.                if (!matches(c, me.name)) {
  2811.                    if (wildcards(c)) remote = -1; else remote = 1;
  2812.                    while (*param && *param != ' ') param++; 
  2813.                          if (*param) param++;
  2814.                          if (!*param) {
  2815.                             sendto_one(sptr,
  2816.                                        "NOTICE %s :#?# No option specified.", 
  2817.                                        sptr->name);
  2818.                             return -1;
  2819.                           }
  2820.            } else return 0;
  2821.      
  2822.         }
  2823.        }
  2824.  if (!IsRegistered(sptr)) { 
  2825.     sendto_one(sptr, ":%s %d * :You have not registered as an user", 
  2826.            me.name, ERR_NOTREGISTERED); 
  2827.     return -1;
  2828.    }
  2829.  if (strlen(param) >= MSG_LEN) {
  2830.     sendto_one(sptr,"NOTICE %s :#?# Line can't be longer than %d chars",
  2831.                sptr->name, MSG_LEN-1);
  2832.     return -1;
  2833.  }
  2834.  for (t = 2; t < 10; t++) {
  2835.       arg = split_string(param, t, 1);
  2836.       switch (*arg) {
  2837.               case '&' :
  2838.               case '$' : passwd = passwd_buf;strncpyzt(passwd,arg+1,10);
  2839.                          break; 
  2840.               case '%' : passwd = passwd_buf;strncpyzt(passwd,arg+1,10);
  2841.                          silent = 1; break;
  2842.               case '#' : id = id_buf; strncpyzt(id,arg+1,BUF_LEN); break; 
  2843.               case '+' :
  2844.               case '-' : if (numeric(arg+1)) {
  2845.                              timeout = timeout_buf; 
  2846.                              strncpyzt(timeout,arg,BUF_LEN); 
  2847.               } else { 
  2848.                                    flags = flags_buf;
  2849.                                    strncpyzt(flags,arg,BUF_LEN);  
  2850.                  }
  2851.                           break;
  2852.               default : goto end_loop_case;
  2853.         }
  2854.     } 
  2855.  end_loop_case:;
  2856.  strncpyzt(option_buf, split_string(param, 1, 1), BUF_LEN-1); 
  2857.  strncpyzt(buf1, split_string(param, t, 1), BUF_LEN-1);
  2858.  strncpyzt(buf2, split_string(param, t+1, 1), BUF_LEN-1);
  2859.  strncpyzt(buf3, split_string(param, t+2, 1), BUF_LEN-1);
  2860.  strncpyzt(buf4, split_string(param, t+3, 1), BUF_LEN-1);
  2861.  strcpy(msg_buf, split_string(param, t+1, 0)); msg = msg_buf;
  2862.  option = option_buf;
  2863.  c = msg; while (*c) c++;
  2864.  while (c != msg && *--c == ' '); 
  2865.  if (c != msg) c++; *c = 0;
  2866.  if (!*msg) msg = NULLCHAR;
  2867.  if (!passwd || !*passwd) passwd = wildcard;
  2868.  if (!flags) flags = (char *) "";
  2869.  if (flags && flag_len_error(sptr, flags)) return 0;
  2870.  time (&old_clock_request);
  2871.  
  2872.  if (MyEq(option,"STATS")) msg_stats(sptr, buf1, buf2); else
  2873.  if (MyEq(option,"VERSION")) sendto_one(sptr,"NOTICE %s :Running version %s", 
  2874.                                         sptr->name, VERSION); 
  2875.  else if (remote < 0 && (mycmp(option, "NEWS") || !msg)) return 0; else
  2876.  if (alias_send(sptr,option, &flags, &msg, &timeout) || MyEq(option,"USER")) {
  2877.      if (!*buf1) {
  2878.         if (MyEq(option,"SPY")) check_messages(sptr, sptr, sptr->name, 'g');
  2879.          else sendto_one(sptr,
  2880.                        "NOTICE %s :#?# Please specify at least one argument", 
  2881.                         sptr->name);
  2882.         return 0;
  2883.       }
  2884.      name = buf1;if (!*name) name = wildcard;
  2885.      if (name_len_error(sptr, name)) return 0;
  2886.      if (!timeout || !*timeout) timeout = default_timeout; 
  2887.      if (mycmp(option, "NEWS") || !msg) {
  2888.          msg_send(sptr, silent, passwd, flags, timeout, name, msg);
  2889.       } else msg_news(sptr, silent, passwd, flags, 
  2890.                       timeout == default_timeout ? deft : timeout, 
  2891.                       name, msg);
  2892.   } else
  2893.  if (MyEq(option,"LS") || MyEq(option,"COUNT") 
  2894.      || MyEq(option,"LOG") || MyEq(option,"LLOG")) {
  2895.      name = buf1;if (name_len_error(sptr, name)) return 0;
  2896.      msg_list(sptr, option, passwd, flags, id, name, buf2);
  2897.    } else
  2898.  if (MyEq(option,"SAVE")) msg_save(sptr); else
  2899.  if (MyEq(option,"ANTIWALL")) antiwall(sptr); else
  2900.  if (MyEq(option,"FLAG")) {
  2901.      name = buf1;if (!*name) name = wildcard;
  2902.      if (name_len_error(sptr, name)) return 0;
  2903.      msg_flag(sptr, passwd, flags, id, name, buf2); 
  2904.   } else
  2905.  if (MyEq(option,"SENT")) {
  2906.     name = buf2;if (!*name) name = wildcard;
  2907.     if (name_len_error(sptr, name)) return 0;
  2908.     msg_sent(sptr, buf1, name, buf3, buf4);
  2909.   } else
  2910.  if (!mycmp(option,"RM")) {
  2911.      if (!*buf1 && !id && !*flags) {
  2912.         sendto_one(sptr,
  2913.                    "NOTICE %s :#?# Please specify at least one argument", 
  2914.                    sptr->name);
  2915.         return 0;
  2916.       }
  2917.      name = buf1;if (!*name) name = wildcard;
  2918.      if (name_len_error(sptr, name)) return 0;
  2919.      msg_remove(sptr, passwd, flags, id, name, buf2); 
  2920.   } else sendto_one(sptr,"NOTICE %s :#?# No such option: %s", 
  2921.                     sptr->name, option);
  2922.  return 0;
  2923. }
  2924. #endif
  2925.