fix possible crash on user deletion
[srvx.git] / patches / asuka-sethost.diff
1 diff -urN srvx_original2/hash.h apples_backup/hash.h
2 --- srvx_original2/hash.h       Mon Jun  2 22:05:38 2003
3 +++ apples_backup/hash.h        Mon Jun  2 21:53:53 2003
4 @@ -48,7 +48,11 @@
5  #define FLAGS_DEAF             0x0020 /* deaf +d */
6  #define FLAGS_SERVICE          0x0040 /* cannot be kicked, killed or deoped +k */
7  #define FLAGS_GLOBAL           0x0080 /* receives global messages +g */
8 -#define FLAGS_HELPER           0x0100 /* (network?) helper +h */
9 +
10 +// apples - sethost 
11 +// #define FLAGS_HELPER                0x0100 /* (network?) helper +h */
12 +#define FLAGS_SETHOST           0x0100 /* for +h */
13 +
14  #define FLAGS_PERSISTENT       0x0200 /* for reserved nicks, this isn't just one-shot */
15  #define FLAGS_GAGGED           0x0400 /* for gagged users */
16  #define FLAGS_AWAY             0x0800 /* for away users */
17 @@ -63,7 +67,11 @@
18  #define IsGlobal(x)             ((x)->modes & FLAGS_GLOBAL)
19  #define IsWallOp(x)             ((x)->modes & FLAGS_WALLOP)
20  #define IsServNotice(x)         ((x)->modes & FLAGS_SERVNOTICE)
21 -#define IsHelperIrcu(x)         ((x)->modes & FLAGS_HELPER)
22 +
23 +// apples - sethost
24 +// #define IsHelperIrcu(x)         ((x)->modes & FLAGS_HELPER)
25 +#define IsSetHost(x)            ((x)->modes & FLAGS_SETHOST)
26 +
27  #define IsGagged(x)             ((x)->modes & FLAGS_GAGGED)
28  #define IsAway(x)               ((x)->modes & FLAGS_AWAY)
29  #define IsStamped(x)            ((x)->modes & FLAGS_STAMPED)
30 @@ -103,6 +111,9 @@
31      unsigned int dead : 1;
32      unsigned long ip;
33      long modes;                   /* user flags +isw etc... */
34 +
35 +    // apples - sethost
36 +    char sethost[USERLEN + HOSTLEN + 2]; /* 1 for '\0' and 1 for @ = 2 */
37  
38      time_t timestamp;
39      struct server *uplink;
40 diff -urN srvx_original2/opserv.c apples_backup/opserv.c
41 --- srvx_original2/opserv.c     Mon Jun  2 22:05:20 2003
42 +++ apples_backup/opserv.c      Mon Jun  2 21:54:03 2003
43 @@ -1229,7 +1229,11 @@
44         if (IsOper(target)) buffer[bpos++] = 'o';
45         if (IsGlobal(target)) buffer[bpos++] = 'g';
46         if (IsServNotice(target)) buffer[bpos++] = 's';
47 -       if (IsHelperIrcu(target)) buffer[bpos++] = 'h';
48 +       
49 +        // apples - sethost
50 +        // if (IsHelperIrcu(target)) buffer[bpos++] = 'h';
51 +        if (IsSetHost(target)) buffer[bpos++] = 'h';
52 +
53         if (IsService(target)) buffer[bpos++] = 'k';
54         if (IsDeaf(target)) buffer[bpos++] = 'd';
55          if (IsHiddenHost(target)) buffer[bpos++] = 'x';
56 diff -urN srvx_original2/proto-common.c apples_backup/proto-common.c
57 --- srvx_original2/proto-common.c       Mon Jun  2 22:05:06 2003
58 +++ apples_backup/proto-common.c        Mon Jun  2 21:53:46 2003
59 @@ -537,13 +537,26 @@
60          nickname = "*";
61      }
62      if (options & GENMASK_STRICT_IDENT) {
63 -        ident = user->ident;
64 +        // apples - sethost
65 +        if (IsSetHost(user)) {
66 +          ident = alloca(strcspn(user->sethost, "@")+2);
67 +          safestrncpy(ident, user->sethost, strcspn(user->sethost, "@")+1);
68 +        }
69 +        else
70 +          ident = user->ident;
71      } else if (options & GENMASK_ANY_IDENT) {
72          ident = "*";
73      } else {
74 -        ident = alloca(strlen(user->ident)+2);
75 -        ident[0] = '*';
76 -        strcpy(ident+1, user->ident + ((*user->ident == '~')?1:0));
77 +        // apples - sethost
78 +        if (IsSetHost(user)) {
79 +          ident = alloca(strcspn(user->sethost, "@")+3);
80 +          ident[0] = '*';
81 +          safestrncpy(ident+1, user->sethost, strcspn(user->sethost, "@")+1);
82 +        } else {
83 +          ident = alloca(strlen(user->ident)+2);
84 +          ident[0] = '*';
85 +          strcpy(ident+1, user->ident + ((*user->ident == '~')?1:0));
86 +        }
87      }
88      hostname = user->hostname;
89      if (IsHiddenHost(user) && user->handle_info && hidden_host_suffix && !(options & GENMASK_NO_HIDING)) {
90 @@ -604,15 +617,20 @@
91             sprintf(hostname, "*.%s", user->hostname+ii+2);
92         }
93      }
94 -    /* Emit hostmask */
95 -    len = strlen(ident) + strlen(hostname) + 2;
96 -    if (nickname) {
97 -        len += strlen(nickname) + 1;
98 -        mask = malloc(len);
99 -        sprintf(mask, "%s!%s@%s", nickname, ident, hostname);
100 -    } else {
101 -        mask = malloc(len);
102 -        sprintf(mask, "%s@%s", ident, hostname);
103 -    }
104 +    // apples - sethost
105 +    if (IsSetHost(user)) 
106 +      hostname = strchr(user->sethost, '@') + 1;
107 +
108 +      /* Emit hostmask */
109 +      len = strlen(ident) + strlen(hostname) + 2;
110 +      if (nickname) {
111 +          len += strlen(nickname) + 1;
112 +          mask = malloc(len);
113 +          sprintf(mask, "%s!%s@%s", nickname, ident, hostname);
114 +      } else {
115 +          mask = malloc(len);
116 +          sprintf(mask, "%s@%s", ident, hostname);
117 +      }
118 +
119      return mask;
120  }
121 diff -urN srvx_original2/proto-p10.c apples_backup/proto-p10.c
122 --- srvx_original2/proto-p10.c  Mon Jun  2 22:04:54 2003
123 +++ apples_backup/proto-p10.c   Mon Jun  2 21:53:32 2003
124 @@ -293,7 +293,8 @@
125  static unsigned int num_notice_funcs;
126  static struct dict *unbursted_channels;
127  
128 -static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *account, const char *numeric, const char *userinfo, time_t timestamp, const char *realip);
129 +// apples - sethost
130 +static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *account, const char *numeric, const char *userinfo, time_t timestamp, const char *realip, const char *sethost);
131  
132  /* Numerics can be XYY, XYYY, or XXYYY; with X's identifying the
133   * server and Y's indentifying the client on that server. */
134 @@ -397,7 +398,11 @@
135          if (IsServNotice(user)) modes[modelen++] = 's';
136          if (IsDeaf(user)) modes[modelen++] = 'd';
137          if (IsGlobal(user)) modes[modelen++] = 'g';
138 -        if (IsHelperIrcu(user)) modes[modelen++] = 'h';
139 +
140 +        // apples - set host
141 +        // if (IsHelperIrcu(user)) modes[modelen++] = 'h';
142 +        if (IsSetHost(user)) modes[modelen++] = 'h';
143 +
144          if (IsHiddenHost(user)) modes[modelen++] = 'x';
145          modes[modelen] = 0;
146  
147 @@ -948,6 +953,8 @@
148  static CMD_FUNC(cmd_nick)
149  {
150      struct userNode *user;
151 +    int i; // apples - sethost
152 +
153      if ((user = GetUserH(origin))) {
154          /* nick change (since the source is a user numeric) */
155          if (argc < 2) return 0;
156 @@ -959,14 +966,26 @@
157          serv = GetServerH(origin);
158          if (argv[6][0] == '+') {
159              if (argc < 10) return 0;
160 -            if (argc > 10) {
161 -                /* The user is +r and has an ACCOUNT stamp in argv[7]. */
162 -                AddUser(serv, argv[1], argv[4], argv[5], argv[6], argv[7], argv[9], argv[argc-1], atoi(argv[3]), argv[8]);
163 -            } else {
164 -                AddUser(serv, argv[1], argv[4], argv[5], argv[6], NULL, argv[8], argv[argc-1], atoi(argv[3]), argv[7]);
165 +
166 +            // apples - sethost
167 +            if ((strchr(argv[6],'h')) && (strchr(argv[6],'r'))) { // +rh
168 +              i = 0;
169 +              while ((argv[6][i] != 'r') && (argv[6][i] != 'h')) i++;
170 +              if (argv[6][i] == 'r') // +r came before +h
171 +                AddUser(serv, argv[1], argv[4], argv[5], argv[6], argv[7], argv[10], argv[argc-1], atoi(argv[3]), argv[9], argv[8]);
172 +              else // +h came before +r
173 +                AddUser(serv, argv[1], argv[4], argv[5], argv[6], argv[8], argv[10], argv[argc-1], atoi(argv[3]), argv[9], argv[7]); 
174 +            }
175 +            else {
176 +              if (strchr(argv[6],'h')) // +h-r
177 +                AddUser(serv, argv[1], argv[4], argv[5], argv[6], NULL, argv[9], argv[argc-1], atoi(argv[3]), argv[8], argv[7]);
178 +              else if (strchr(argv[6],'r')) // +r-h
179 +                AddUser(serv, argv[1], argv[4], argv[5], argv[6], argv[7], argv[9], argv[argc-1], atoi(argv[3]), argv[8], NULL);
180 +              else // -rh
181 +                AddUser(serv, argv[1], argv[4], argv[5], argv[6], NULL, argv[8], argv[argc-1], atoi(argv[3]), argv[7], NULL);
182              }
183          } else {
184 -            AddUser(serv, argv[1], argv[4], argv[5], "+", NULL, argv[7], argv[argc-1], atoi(argv[3]), argv[6]);
185 +            AddUser(serv, argv[1], argv[4], argv[5], "+", NULL, argv[7], argv[argc-1], atoi(argv[3]), argv[6], NULL);
186          }
187      }
188      return 1;
189 @@ -1057,6 +1076,8 @@
190      struct chanNode *cn;
191      struct userNode *un;
192      const char *modes;
193 +    char *sethost; // apples - sethost
194 +    int i; // apples - sethost
195  
196      if (argc < 3) {
197          return 0;
198 @@ -1067,7 +1088,19 @@
199              log(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose mode is changing\n", argv[1]);
200              return 0;
201          }
202 -        mod_usermode(un, argv[2]);
203 +        // apples - sethost
204 +        if (argc == 3)
205 +          mod_usermode(un, argv[2]);
206 +        else {
207 +          sethost = malloc(strlen(argv[2]) + 1 + strlen(argv[3]) + 1);
208 +          i = 0;
209 +          while((sethost[i++] = *argv[2]++));
210 +          i--; 
211 +          sethost[i++] = ' ';
212 +          while((sethost[i++] = *argv[3]++)); 
213 +          mod_usermode(un, sethost); // apples - sethost
214 +        }       
215 +
216          return 1;
217      }
218  
219 @@ -1733,7 +1766,7 @@
220      }
221      make_numeric(self, local_num, numeric);
222      if (old_user) timestamp = old_user->timestamp - 1;
223 -    return AddUser(self, nick, nick, self->name, "+oik", NULL, numeric, desc, now, "AAAAAA");
224 +    return AddUser(self, nick, nick, self->name, "+oik", NULL, numeric, desc, now, "AAAAAA", NULL); // apples - sethost
225  }
226  
227  struct userNode *
228 @@ -1750,7 +1783,7 @@
229      }
230      make_numeric(self, local_num, numeric);
231      if (old_user) timestamp = old_user->timestamp - 1;
232 -    return AddUser(self, nick, ident, hostname, "+i", NULL, numeric, desc, timestamp, "AAAAAA");
233 +    return AddUser(self, nick, ident, hostname, "+i", NULL, numeric, desc, timestamp, "AAAAAA", NULL); // apples - sethost
234  }
235  
236  int
237 @@ -1765,12 +1798,14 @@
238      return 1;
239  }
240  
241 +// apples - sethost
242  static struct userNode*
243 -AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *account, const char *numeric, const char *userinfo, time_t timestamp, const char *realip)
244 +AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *account, const char *numeric, const char *userinfo, time_t timestamp, const char *realip, const char *sethost)
245  {
246      struct userNode *oldUser, *uNode;
247      struct policer_params *pol_params;
248      unsigned int n, ignore_user;
249 +    char *newmodes; // apples - sethost
250  
251      if ((strlen(numeric) < 3) || (strlen(numeric) > 5)) {
252          log(MAIN_LOG, LOG_WARNING, "AddUser(%p, %s, ...): numeric %s wrong length!\n", uplink, nick, numeric);
253 @@ -1829,7 +1864,22 @@
254      uNode->num_local = base64toint(numeric+strlen(uNode->uplink->numeric), 3) & uNode->uplink->num_mask;
255      uNode->uplink->users[uNode->num_local] = uNode;
256      if (account) call_account_func(uNode, account);
257 -    mod_usermode(uNode, modes);
258
259 +    // apples - sethost
260 +    if (sethost) {
261 +      newmodes = malloc(strlen(modes) + 1 + strlen(sethost) + 1);
262 +      n = 0;
263 +      while ((newmodes[n] = modes[n])) n++;
264 +      newmodes[n++] = ' ';
265 +      while ((newmodes[n] = *sethost)) { 
266 +        n++; 
267 +        sethost++; 
268 +      }
269 +      mod_usermode(uNode, newmodes);
270 +    }
271 +    else
272 +      mod_usermode(uNode, modes);
273 +
274      if (ignore_user) return uNode;
275  
276      dict_insert(clients, uNode->nick, uNode);
277 @@ -1899,8 +1949,10 @@
278      extern struct policer_params *oper_policer_params, *luser_policer_params;
279      static void call_oper_funcs(struct userNode *user);
280      int add = 1;
281 +    int i = 0;
282  
283      if (!user || !mode_change) return;
284
285      while (1) {
286  #define do_user_mode(FLAG) do { if (add) user->modes |= FLAG; else user->modes &= ~FLAG; } while (0)
287         switch (*mode_change++) {
288 @@ -1931,7 +1983,18 @@
289         case 'd': do_user_mode(FLAGS_DEAF); break;
290         case 'k': do_user_mode(FLAGS_SERVICE); break;
291         case 'g': do_user_mode(FLAGS_GLOBAL); break;
292 -       case 'h': do_user_mode(FLAGS_HELPER); break;
293 +
294 +        // apples - sethosti
295 +        // don't need this anymore vvvvvv
296 +       // case 'h': do_user_mode(FLAGS_HELPER); break;
297 +        // so basically, +h is the only mode that requires a parameter for the time
298 +        // being, so i check if there's an 'h' in the first part, and if there is 
299 +        // then everything after the space becomes their new host
300 +        case 'h': do_user_mode(FLAGS_SETHOST); break;
301 +        case ' ': if (IsSetHost(user))
302 +                    while ((user->sethost[i++] = *mode_change++)); 
303 +                  break;  
304 +                  
305          case 'x': do_user_mode(FLAGS_HIDDEN_HOST); break;
306         }
307  #undef do_user_mode
308 diff -urN srvx_original2/tools.c apples_backup/tools.c
309 --- srvx_original2/tools.c      Mon Jun  2 22:05:28 2003
310 +++ apples_backup/tools.c       Mon Jun  2 21:53:21 2003
311 @@ -291,6 +291,9 @@
312  user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick)
313  {
314      char *glob, *marker;
315 +    int usingreal = 0; // apples - sethost
316 +    int usingset = 0; // apples - sethost
317 +    char *setident, *sethostname; // apples - sethost
318  
319      /* Make a writable copy of the glob */
320      glob = alloca(strlen(orig_glob)+1);
321 @@ -311,22 +314,37 @@
322          return 0;
323      }
324      *marker = 0;
325 -    if (!match_ircglob(user->ident, glob)) return 0;
326 +    
327 +    // apples - sethost
328 +    if (match_ircglob(user->ident, glob)) usingreal = 1;
329 +    if (IsSetHost(user)) {
330 +          setident = alloca(strcspn(user->sethost, "@")+2);
331 +          safestrncpy(setident, user->sethost, strcspn(user->sethost, "@")+1);
332 +          if (match_ircglob(setident, glob)) usingset = 1;
333 +    }
334 +
335      glob = marker + 1;
336      /* Now check the host part */
337 +
338 +    // apples - sethost
339 +    if (IsSetHost(user)) {
340 +      sethostname = strchr(user->sethost, '@') + 1;
341 +      if (match_ircglob(sethostname, glob) && usingset) return 1;
342 +    }
343 +
344      if (isdigit(*glob) && !glob[strspn(glob, "0123456789./*?")]) {
345          /* Looks like an IP-based mask */
346          unsigned char userip[20];
347          sprintf(userip, "%ld.%ld.%ld.%ld", (user->ip >> 24) & 255, (user->ip >> 16) & 255, (user->ip >> 8) & 255, user->ip & 255);
348 -        return match_ircglob(userip, glob);
349 +        return match_ircglob(userip, glob) && usingreal;
350      } else {
351          if (hidden_host_suffix && user->handle_info) {
352              char hidden_host[HOSTLEN+1];
353              snprintf(hidden_host, sizeof(hidden_host), "%s.%s", user->handle_info->handle, hidden_host_suffix);
354 -            if (match_ircglob(hidden_host, glob)) return 1;
355 +            if (match_ircglob(hidden_host, glob) && usingreal) return 1;
356          }
357          /* The host part of the mask isn't IP-based */
358 -        return match_ircglob(user->hostname, glob);
359 +        return match_ircglob(user->hostname, glob) && usingreal;
360      }
361  }
362