fix possible crash on user deletion
[srvx.git] / patches / sethost13.diff
1 diff -purN -x {arch} srvx-1.3/src/hash.h srvx-1.3~reed-sethost/src/hash.h
2 --- srvx-1.3/src/hash.h 2004-05-24 16:51:58.000000000 -0600
3 +++ srvx-1.3~reed-sethost/src/hash.h    2004-05-22 20:01:21.000000000 -0600
4 @@ -51,7 +51,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 +// sethost - reed/apples
11 +// #define FLAGS_HELPER                0x0100 /* (network?) helper +h */
12 +#define FLAGS_SETHOST          0x0100 /* sethost +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 @@ -67,7 +71,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 +// sethost - reed/apples
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 IsPersistent(x)         ((x)->modes & FLAGS_PERSISTENT) 
29  #define IsAway(x)               ((x)->modes & FLAGS_AWAY)
30 @@ -111,6 +119,9 @@ struct userNode {
31      struct in_addr ip;            /* User's IP address */
32      long modes;                   /* user flags +isw etc... */
33  
34 +    // sethost - reed/apples
35 +    char sethost[USERLEN + HOSTLEN + 2]; /* 1 for '\0' and 1 for @ = 2 */
36 +
37      time_t timestamp;             /* Time of last nick change */
38      struct server *uplink;        /* Server that user is connected to */
39      struct modeList channels;     /* Vector of channels user is in */
40 diff -purN -x {arch} srvx-1.3/src/opserv.c srvx-1.3~reed-sethost/src/opserv.c
41 --- srvx-1.3/src/opserv.c       2004-05-24 16:51:58.000000000 -0600
42 +++ srvx-1.3~reed-sethost/src/opserv.c  2004-05-22 20:01:21.000000000 -0600
43 @@ -1180,7 +1180,11 @@ static MODCMD_FUNC(cmd_whois)
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 +       // sethost - reed/apples
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 -purN -x {arch} srvx-1.3/src/proto-common.c srvx-1.3~reed-sethost/src/proto-common.c
57 --- srvx-1.3/src/proto-common.c 2004-05-24 16:51:58.000000000 -0600
58 +++ srvx-1.3~reed-sethost/src/proto-common.c    2004-05-22 20:01:21.000000000 -0600
59 @@ -662,14 +662,27 @@ generate_hostmask(struct userNode *user,
60      else
61          nickname = "*";
62      if (options & GENMASK_STRICT_IDENT)
63 +        // sethost - reed/apples
64 +        if (IsSetHost(user)) {
65 +          ident = alloca(strcspn(user->sethost, "@")+2);
66 +          safestrncpy(ident, user->sethost, strcspn(user->sethost, "@")+1);
67 +        }
68 +        else
69          ident = user->ident;
70      else if (options & GENMASK_ANY_IDENT)
71          ident = "*";
72      else {
73 +        // sethost - reed/apples
74 +        if (IsSetHost(user)) {
75 +          ident = alloca(strcspn(user->sethost, "@")+3);
76 +          ident[0] = '*';
77 +          safestrncpy(ident+1, user->sethost, strcspn(user->sethost, "@")+1);
78 +        } else {
79          ident = alloca(strlen(user->ident)+2);
80          ident[0] = '*';
81          strcpy(ident+1, user->ident + ((*user->ident == '~')?1:0));
82      }
83 +    }
84      hostname = user->hostname;
85      if (IsFakeHost(user) && IsHiddenHost(user) && !(options & GENMASK_NO_HIDING)) {
86          hostname = user->fakehost;
87 @@ -727,6 +740,10 @@ generate_hostmask(struct userNode *user,
88              sprintf(hostname, "*.%s", user->hostname+ii+2);
89          }
90      }
91 +    // sethost - reed/apples
92 +    if (IsSetHost(user)) 
93 +      hostname = strchr(user->sethost, '@') + 1;
94 +
95      /* Emit hostmask */
96      len = strlen(ident) + strlen(hostname) + 2;
97      if (nickname) {
98 diff -purN -x {arch} srvx-1.3/src/proto-p10.c srvx-1.3~reed-sethost/src/proto-p10.c
99 --- srvx-1.3/src/proto-p10.c    2004-05-24 16:51:58.000000000 -0600
100 +++ srvx-1.3~reed-sethost/src/proto-p10.c       2004-05-22 20:58:36.000000000 -0600
101 @@ -400,8 +400,12 @@ irc_user(struct userNode *user)
102              modes[modelen++] = 'd';
103          if (IsGlobal(user))
104              modes[modelen++] = 'g';
105 -        if (IsHelperIrcu(user))
106 +        // sethost - reed/apples
107 +        // if (IsHelperIrcu(user))
108 +        if (IsSetHost(user))
109              modes[modelen++] = 'h';
110 +        if (IsFakeHost(user))
111 +            modes[modelen++] = 'f';
112          if (IsHiddenHost(user))
113              modes[modelen++] = 'x';
114          modes[modelen] = 0;
115 @@ -1099,6 +1103,8 @@ static CMD_FUNC(cmd_mode)
116  {
117      struct chanNode *cn;
118      struct userNode *un;
119 +    char *sethost; // sethost - reed/apples
120 +    int i; // sethost - reed/apples
121  
122      if (argc < 3)
123          return 0;
124 @@ -1108,7 +1114,19 @@ static CMD_FUNC(cmd_mode)
125              log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose mode is changing.", argv[1]);
126              return 0;
127          }
128 +        // sethost - reed/apples
129 +        if (argc == 3)
130          mod_usermode(un, argv[2]);
131 +        else {
132 +          sethost = malloc(strlen(argv[2]) + 1 + strlen(argv[3]) + 1);
133 +          i = 0;
134 +          while((sethost[i++] = *argv[2]++));
135 +          i--;
136 +         sethost[i++] = ' ';
137 +          while((sethost[i++] = *argv[3]++));
138 +          mod_usermode(un, sethost); // sethost - reed/apples
139 +        }
140 +
141          return 1;
142      }
143  
144 @@ -2018,7 +2036,22 @@ void mod_usermode(struct userNode *user,
145         case 'd': do_user_mode(FLAGS_DEAF); break;
146         case 'k': do_user_mode(FLAGS_SERVICE); break;
147         case 'g': do_user_mode(FLAGS_GLOBAL); break;
148 -       case 'h': do_user_mode(FLAGS_HELPER); break;
149 +       // sethost - reed/apples
150 +       // case 'h': do_user_mode(FLAGS_HELPER); break;
151 +       // I check if there's an 'h' in the first part, and if there, 
152 +       // then everything after the space becomes their new host.
153 +       case 'h': do_user_mode(FLAGS_SETHOST);
154 +           if (*word) {
155 +               char sethost[MAXLEN];
156 +               unsigned int ii;
157 +               for (ii=0; (*word != ' ') && (*word != '\0'); )
158 +                   sethost[ii++] = *word++;
159 +               sethost[ii] = 0;
160 +               while (*word == ' ')
161 +                   word++;
162 +               safestrncpy(user->sethost, sethost, sizeof(user->sethost));
163 +           }
164 +           break;
165          case 'x': do_user_mode(FLAGS_HIDDEN_HOST); break;
166          case 'r':
167              if (*word) {
168 diff -purN -x {arch} srvx-1.3/src/tools.c srvx-1.3~reed-sethost/src/tools.c
169 --- srvx-1.3/src/tools.c        2004-05-24 16:51:58.000000000 -0600
170 +++ srvx-1.3~reed-sethost/src/tools.c   2004-05-22 21:10:26.000000000 -0600
171 @@ -311,6 +311,7 @@ int
172  user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick)
173  {
174      char *glob, *marker;
175 +    char *setident = NULL, *sethostname = NULL; // sethost - reed/apples
176  
177      /* Make a writable copy of the glob */
178      glob = alloca(strlen(orig_glob)+1);
179 @@ -331,8 +332,16 @@ user_matches_glob(struct userNode *user,
180          return 0;
181      }
182      *marker = 0;
183 -    if (!match_ircglob(user->ident, glob))
184 -        return 0;
185 +
186 +    // sethost - reed/apples
187 +    if (IsSetHost(user)) {
188 +      setident = alloca(strcspn(user->sethost, "@")+2);
189 +      safestrncpy(setident, user->sethost, strcspn(user->sethost, "@")+1);
190 +      sethostname = strchr(user->sethost, '@') + 1;
191 +    }
192 +
193 +    if (!match_ircglob(user->ident, glob) && (IsSetHost(user) && !match_ircglob(setident, glob)))
194 +       return 0;
195      glob = marker + 1;
196      /* Now check the host part */
197      if (isdigit(*glob) && !glob[strspn(glob, "0123456789./*?")]) {
198 @@ -340,6 +349,8 @@ user_matches_glob(struct userNode *user,
199          return match_ircglob(inet_ntoa(user->ip), glob);
200      } else {
201          /* The host part of the mask isn't IP-based */
202 +        if (IsSetHost(user) && match_ircglob(sethostname, glob))
203 +                return 1;
204          if (IsFakeHost(user) && match_ircglob(user->fakehost, glob))
205                  return 1;
206          if (hidden_host_suffix && user->handle_info) {