1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 1997-2021 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 * USA
20 */
21
22 /*! \file id.c
23 * \brief Contains functions pertaining to SID/UID generation.
24 * \version $Id: id.c 9858 2021-01-01 04:43:42Z michael $
25 */
26
27 #include "stdinc.h"
28 #include "id.h"
29 #include "irc_string.h"
30 #include "client.h"
31
32 static char new_uid[TOTALSIDUID + 1]; /* Allow for \0 */
33
34 bool
valid_sid(const char * sid)35 valid_sid(const char *sid)
36 {
37 if (strlen(sid) != IRC_MAXSID)
38 return false;
39
40 if (!IsDigit(*sid))
41 return false;
42
43 for (unsigned int i = 1; i < IRC_MAXSID; ++i)
44 if (!IsUpper(*(sid + i)) && !IsDigit(*(sid + i)))
45 return false;
46
47 return true;
48 }
49
50 bool
valid_uid(const char * uid)51 valid_uid(const char *uid)
52 {
53 if (strlen(uid) != TOTALSIDUID)
54 return false;
55
56 if (!IsDigit(*uid))
57 return false;
58
59 for (unsigned int i = 1; i < TOTALSIDUID; ++i)
60 if (!IsUpper(*(uid + i)) && !IsDigit(*(uid + i)))
61 return false;
62
63 return true;
64 }
65
66 /*
67 * init_uid()
68 *
69 * inputs - NONE
70 * output - NONE
71 * side effects - new_uid is filled in with server id portion (sid)
72 * (first 3 bytes). Rest is filled in with '9'.
73 *
74 */
75 void
init_uid(void)76 init_uid(void)
77 {
78 snprintf(new_uid, sizeof(new_uid), "%s999999", me.id);
79 }
80
81 /*
82 * add_one_to_uid
83 *
84 * inputs - index number into new_uid
85 * output - NONE
86 * side effects - new_uid is incremented by one
87 * note this is a recursive function
88 */
89 static void
add_one_to_uid(unsigned int i)90 add_one_to_uid(unsigned int i)
91 {
92 if (i < IRC_MAXSID)
93 return;
94
95 if (new_uid[i] == 'Z')
96 new_uid[i] = '0';
97 else if (new_uid[i] == '9')
98 {
99 new_uid[i] = 'A';
100 add_one_to_uid(i - 1);
101 }
102 else
103 ++new_uid[i];
104 }
105
106 /*
107 * uid_get
108 *
109 * inputs - struct Client *
110 * output - new UID is returned to caller
111 * side effects - new_uid is incremented by one.
112 */
113 const char *
uid_get(void)114 uid_get(void)
115 {
116 add_one_to_uid(TOTALSIDUID - 1); /* Index from 0 */
117 return new_uid;
118 }
119
120 void
generate_sid(void)121 generate_sid(void)
122 {
123 unsigned int sid = 0;
124 const char *p;
125
126 for (p = me.name; *p; ++p)
127 sid = 5 * sid + *p;
128 for (p = me.info; *p; ++p)
129 sid = 5 * sid + *p;
130
131 snprintf(me.id, IRC_MAXSID + 1, "%03d", sid % 1000);
132 }
133