1 /*
2 * nicks.c
3 *
4 * this file contains code to implement nick name related stuff.
5 *
6 * written by Joshua J. Drake
7 * copyright (c) 1998
8 */
9
10 #include "irc.h"
11 #include "ircaux.h"
12 #include "nicks.h"
13 #include "dma.h"
14 #include "list.h"
15 #include "server.h"
16 #include "output.h"
17 #include "channels.h"
18 #include "numbers.h"
19
20 /* islegal: true if c is a legal nickname char anywhere but first char */
21 #define islegal(c) ((((c) >= 'A') && ((c) <= '}')) || \
22 (((c) >= '0') && ((c) <= '9')) || \
23 ((c) == '-') || ((c) == '_'))
24
25
26 u_char *old_nick = UNULL;
27
28 static u_char *randcrap _((int));
29
30 /*
31 * checkNick()
32 * checks to see if a nick name is legal. it will check the first character first.
33 * if it is legal we return from here to the first illegal character. if the first
34 * character is invalid, we return NULL.
35 *
36 **** rewritten, with help from do_nick_name() from the server code (2.8.5),
37 **** phone, april 1993.
38 *
39 * moved to nicks.c 11/13/98
40 */
41 u_char *
check_nick(nick)42 check_nick(nick)
43 u_char *nick;
44 {
45 u_char *s;
46
47 /* check the first character. */
48 if (!nick || *nick == '-' || isdigit(*nick))
49 return NULL;
50
51 /* skip to the first illegal character. */
52 for (s = nick; *s; s++)
53 if (!islegal(*s) || isspace(*s))
54 break;
55 *s = '\0';
56
57 /* if we have something, return it, otherwise forget it. */
58 return *nick ? nick : NULL;
59 }
60
61 void
free_nick(nick)62 free_nick(nick)
63 Nick **nick;
64 {
65 Nick *tmp = *nick;
66
67 dma_Free(&(tmp->nick));
68 dma_Free(&(tmp->user));
69 dma_Free(&(tmp->host));
70 dma_Free(&(tmp->realname));
71 dma_Free(&(tmp->server));
72 dma_Free(&tmp);
73 }
74
75 /*
76 * find a nick on a channel on a server
77 *
78 * this will find a nick ptr via the channel or tmpchan variable..
79 * the tmpchan is preferred as it doesn't require lookup_channel..
80 *
81 */
82 Nick *
find_nick(u_char * nick,u_char * channel,int server,Channel * tmpchan)83 find_nick(u_char *nick, u_char *channel, int server, Channel *tmpchan)
84 {
85 Channel *chan;
86
87 if (!nick || (!tmpchan && !channel) || server < 0 || server >= number_of_servers)
88 return NULL;
89
90 /* tmpchan is preferred */
91 if (tmpchan)
92 {
93 if (tmpchan->server != server)
94 {
95 put_error("findnick() received bad Channel pointer server!=%d", server);
96 return NULL;
97 }
98 return (Nick *) find_in_list((List **)&tmpchan->nicks, nick, !USE_WILDCARDS);
99 }
100
101 /* okay fine, we'll look it up */
102 chan = lookup_channel(channel, server, 0);
103 if (!chan) /* we're not on the channel! */
104 return NULL;
105
106 /* return it! */
107 return (Nick *) find_in_list((List **)&chan->nicks, nick, !USE_WILDCARDS);
108 }
109
110
111 /*
112 * this will rotate your nickname characters and send it to the server
113 */
114 #define MAX_AUTO_NICK_ATTEMPTS 6
115 void
rotate_nick(nick)116 rotate_nick(nick)
117 u_char *nick;
118 {
119 static int rot_att_cnt = 1; /* count of how many rotations attempts in a row we've done */
120 int nicklen = 0, i;
121
122 if (!attempting_to_connect)
123 return;
124
125 /* put_info("passed in: %s (%s #%u)", nick, old_nick, rot_att_cnt); */
126
127 /* same as we just passed out? */
128 if (!my_stricmp(old_nick, nick))
129 {
130 rot_att_cnt++;
131 if (rot_att_cnt == (MAX_AUTO_NICK_ATTEMPTS - 1))
132 {
133 /* one last shot! lets try random */
134 dma_strcpy(&old_nick, randcrap(12));
135 send_to_server("NICK %s", old_nick);
136 return;
137 }
138 else if (rot_att_cnt >= MAX_AUTO_NICK_ATTEMPTS)
139 {
140 /* absolute last resort: manual intervention */
141 reset_nickname();
142 rot_att_cnt = 1;
143 return;
144 }
145 }
146 else /* if we're not looping, reset the attempt counter */
147 rot_att_cnt = 1;
148
149 /* rotate the nickname */
150 nicklen = my_strlen(nick);
151 dma_strcpy(&old_nick, nick);
152 if (!old_nick)
153 {
154 reset_nickname(); /* bleh, must be out of memory */
155 return;
156 }
157
158 for (i = 0; i < nicklen-1; i++)
159 old_nick[i] = old_nick[i+1];
160 old_nick[nicklen-1] = *nick;
161 /* send it to the server */
162 /* put_info("sending to server: %s", old_nick); */
163 send_to_server("NICK %s", old_nick);
164 }
165
166
167 /*
168 * return len of random isalpha()s
169 */
170 static u_char *
randcrap(len)171 randcrap(len)
172 int len;
173 {
174 static u_char rstr[128];
175 u_char all[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\[]{}-_|^`";
176 int i, t;
177 long int r;
178 float alen = my_strlen(all);
179
180 srandom(time(NULL)/rand());
181 r = random();
182 #ifndef _Windows
183 srand(r*getpid());
184 #endif
185
186 for (i = 0; i < len && i < sizeof(rstr)-1; i++)
187 {
188 t = (int)(alen * rand() / (RAND_MAX+1.0));
189 // printf("RAND: %d %c\n", t, all[t]);
190 rstr[i] = all[t];
191 }
192 rstr[i] = '\0';
193 return rstr;
194 }
195
196