-
Notifications
You must be signed in to change notification settings - Fork 8
/
gone_server.c
238 lines (206 loc) · 5.88 KB
/
gone_server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/* GONE_SERVER.C V1.1
| These are the routines used to keep the Gone database. They init it, add and
| remove users to it, and log the messages when needed.
|
*/
#include "consts.h"
#include "prototypes.h"
#define MAX_GONES 100
char GoneUsers[MAX_GONES][16];
char *GoneUsersDir[MAX_GONES];
int GoneUsersNum = 0;
/*
| Add a user to the list. We also store his login directory, so the program
| later will not have to look for it each time there is a message to log.
| We keep the list in sorted order, so the search later will be faster (binary
| search).
*/
void
add_gone_user(line)
const char *line;
{
char UserName[128], LoginDirectory[128];
int i, j;
if (GoneUsersNum == (MAX_GONES - 1)) /* No room */
return; /* Ignore it */
if (sscanf(line, "%s %s", UserName, LoginDirectory) != 2) {
logger(1, "GONE_SERVER, Can't get parameters from '%s'\n", line);
return;
}
/* Look for the correct place to put it on the list */
for (i = 0; i < GoneUsersNum; i++) {
if ((j = strcmp(UserName, GoneUsers[i])) == 0)
return; /* Already in there - do nothing */
if (j < 0) /* We have to insert it before
the current one */
break;
}
/* Clear a place for him - Move all entries after it one place higher */
if (i != GoneUsersNum) {
for (j = GoneUsersNum; j >= i; j--) {
strcpy(GoneUsers[j + 1], GoneUsers[j]);
GoneUsersDir[j + 1] = GoneUsersDir[j];
}
}
GoneUsersNum++;
/* And insert it now */
strcpy(GoneUsers[i], UserName);
if ((GoneUsersDir[i] = malloc(strlen(LoginDirectory) + 1)) == NULL) {
logger(1, "GONE_SERVER, Can't malloc.\n");
bug_check("Can't allocate memory for Gone");
}
strcpy(GoneUsersDir[i], LoginDirectory);
}
/*
| Delete a user from the database if he exists there.
*/
void
del_gone_user(UserName)
const char *UserName;
{
int i = 0, j = 0;
char *LoginDirectory; /* Need it to call Get_gone_user */
/* Look for his entry */
if ((i = get_gone_user(UserName, &LoginDirectory)) < 0)
return; /* Not registered */
/* Exists - delete him */
for (j = i; j < GoneUsersNum; j++) {
strcpy(GoneUsers[j], GoneUsers[j + 1]);
GoneUsersDir[j] = GoneUsersDir[j + 1];
}
free(LoginDirectory); /* Free the memory used by him */
GoneUsersNum--;
}
/*
| Try sending the message to the gone user. If he was found and we could
| write it, ok - return -1 as number of users received the message so the
| caller of us will know to return a Gone message. If not, return 0.
*/
#ifdef UNIX
int
send_gone(UserName, string)
const char *UserName;
char *string;
{
char *LoginDirectory, *p, FileName[512];
FILE *fd;
int oldumask;
struct passwd *pwd, *getpwnam();
/* Get login directory and open the file */
if (get_gone_user(UserName, &LoginDirectory) < 0)
return 0; /* Not found */
sprintf(FileName, "%s/.ygone.messages", LoginDirectory);
pwd = getpwnam(UserName);
if (!pwd) return 0; /* What ??? */
oldumask = umask(077);
if ((fd = fopen(FileName, "a")) == NULL) {
logger(1, "GONE_SERVER, Can't open user's file '%s'\n", FileName);
umask(oldumask);
return 0;
}
chown(FileName,pwd->pw_uid,pwd->pw_gid);
umask(oldumask);
/* Remove all control characters from the line and
prepend it with a time stamp */
for (p = string; *p != '\0'; p++)
if (*p < ' ') *p = ' ';
/* Jump over leading spaces */
for (p = string; *p != '\0'; p++)
if (*p != ' ') break;
fprintf(fd, "%s: %s\n", local_time(), p);
fclose(fd);
return -1;
}
#else /* !UNIX */
int
send_gone(UserName, string)
const char *UserName;
char *string;
{
char *LoginDirectory, *p, FileName[128];
FILE *fd;
/* Get login directory and open the file */
if (get_gone_user(UserName, &LoginDirectory) < 0)
return 0; /* Not found */
sprintf(FileName, "%s/.ygone.messages", LoginDirectory);
sprintf(FileName, "%sYGONE_MESSAGES.TXT", LoginDirectory);
if ((fd = fopen(FileName, "a")) == NULL) {
logger(1, "GONE_SERVER, Can't open user's file '%s'\n", FileName);
return 0;
}
/* Remove all controls from line and append it with the time */
for (p = string; *p != '\0'; p++)
if (*p < ' ') *p = ' ';
/* Jump over leading spaces */
for (p = string; *p != '\0'; p++)
if (*p != ' ') break;
fprintf(fd, "%s: %s\n", local_time(), p);
fclose(fd);
return -1;
}
#endif
/*
| Inform to all users in Gone that we shutdown now.
*/
void
shut_gone_users __((void))
{
int i;
for (i = 0; i < GoneUsersNum; i++)
send_gone(GoneUsers[i], "***** NJE emulator shut down *****");
}
/*
| Pass over the list of Gone users (using binary search) and return the
| login directory of that user and the index of it in the GoneUsers array.
| If not found, return -1;
*/
int
get_gone_user(UserName, LoginDirectory)
const char *UserName;
char **LoginDirectory;
{
int First, Last, Middle, /* For binary search */
CompareResult;
/* Do a binary search */
First = 0; Last = GoneUsersNum - 1; /* The last entry */
Middle = (First + Last) / 2;
for (;;) {
if ((CompareResult = strcmp(UserName, GoneUsers[Middle])) == 0) {
*LoginDirectory = GoneUsersDir[Middle];
return Middle;
}
/* Not equal - compute new bottom/up */
if (CompareResult < 0) {
Last = Middle;
Middle = (First + Last) / 2;
} else {
First = Middle;
Middle = (First + Last) / 2;
}
/* Prevent oscillations */
if ((Last - First) <= 1) {
if ((CompareResult = strcmp(UserName, GoneUsers[First])) == 0) {
*LoginDirectory = GoneUsersDir[First];
return First;
}
if ((CompareResult = strcmp(UserName, GoneUsers[Last])) == 0) {
*LoginDirectory = GoneUsersDir[Last];
return Last;
} else
return -1; /* Not found */
}
}
}
/*
| Dump the whole gone list into the logfile.
| This is used when using DEBUG DUMP to help locate problems.
*/
void
dump_gone_list __((void))
{
int i;
logger(1, "** Gone list dump (%d users):\n", GoneUsersNum);
for (i = 0; i < GoneUsersNum; i++)
logger(1, " %s %s\n", GoneUsers[i], GoneUsersDir[i]);
logger(1, "End of gone list\n");
}