admin.c 9.56 KB
Newer Older
Linus Tolke's avatar
Linus Tolke committed
1
/*
2
 * $Id: admin.c,v 0.36 1999/05/16 21:45:00 ceder Exp $
Per Cederqvist's avatar
Per Cederqvist committed
3
 * Copyright (C) 1991, 1993, 1994, 1995, 1996  Lysator Academic Computer Association.
Linus Tolke's avatar
Linus Tolke committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * This file is part of the LysKOM server.
 * 
 * LysKOM is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 1, or (at your option) 
 * any later version.
 * 
 * LysKOM is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with LysKOM; see the file COPYING.  If not, write to
 * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
 * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
 * MA 02139, USA.
 *
 * Please mail bug reports to bug-lyskom@lysator.liu.se. 
 */
Per Cederqvist's avatar
Per Cederqvist committed
25
26
27
28
29
/*
 * admin.c
 *
 * Administrative calls.
 */
Per Cederqvist's avatar
Per Cederqvist committed
30

David Byers's avatar
David Byers committed
31
32
33
34
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

35
static const char *
36
rcsid = "$Id: admin.c,v 0.36 1999/05/16 21:45:00 ceder Exp $";
37
38
#include "rcs.h"
USE(rcsid);
Per Cederqvist's avatar
Per Cederqvist committed
39

Per Cederqvist's avatar
Per Cederqvist committed
40
41
#include <stdio.h>
#include <setjmp.h>
42
43
44
#ifdef HAVE_STDARG_H
#  include <stdarg.h>
#endif
45
46
#include <sys/types.h>
#include <time.h>
47
#include <malloc.h>
48
#include <signal.h>
Per Cederqvist's avatar
Per Cederqvist committed
49
50

#include "misc-types.h"
51
#include "s-string.h"
Per Cederqvist's avatar
Per Cederqvist committed
52
#include "kom-types.h"
Per Cederqvist's avatar
Per Cederqvist committed
53
54
#include "manipulate.h"
#include "com.h"
55
#include "async.h"
Per Cederqvist's avatar
Per Cederqvist committed
56
#include "connections.h"
Per Cederqvist's avatar
Per Cederqvist committed
57
58
#include "kom-errno.h"
#include "cache.h"
David Byers's avatar
David Byers committed
59
#include "kom-config.h"
Per Cederqvist's avatar
Per Cederqvist committed
60
61
#include "log.h"
#include "send-async.h"
62
#include "param.h"
63
#include "string-malloc.h"
64
65
#include "services.h"
#include "version-info.h"
66
#include "aux-items.h"
67
#include "unused.h"
Per Cederqvist's avatar
Per Cederqvist committed
68
#include "sigflags.h"
Per Cederqvist's avatar
Per Cederqvist committed
69

Per Cederqvist's avatar
Per Cederqvist committed
70
71
72
73
74
75
/* All of the fields in this structure except the version number
   is set from the configuration file at startup (see ramkomd.c).
   The default values are also set in ramkomd.c; the values below are
   never used.  The defaults are as of this writing (1994-01-11
   19:57:22) equal to the values below, but don't trust that that is
   so when you read this. */
76

77
78
/* Actually, these values are (except for the server compatibility
   version number) stored in the database */
79

Per Cederqvist's avatar
Per Cederqvist committed
80
81
82
83
84
85
86
87
Info kom_info = 
{
#include "version.incl"
    ,				/* version */
    1,				/* conf_pres_conf */
    2,				/* pers_pres_conf */
    3,				/* motd_conf */
    4,				/* kom_news_conf */
88
89
90
    0,				/* motd_of_lyskom */
    0,                          /* highest_aux_no */
    { 0, NULL }                 /* aux_item_list */
Per Cederqvist's avatar
Per Cederqvist committed
91
92
93
94
};

/*
 * Return info about this server. This can (and should) be done
95
 * before logging in. motd_of_lyskom should be displayed before
Per Cederqvist's avatar
Per Cederqvist committed
96
97
 * prompting for username if it isn't 0.
 */
98
99
100
101
102
103
104
extern Success
get_info_old( Info *result )
{
    *result = kom_info;
    return OK;
}

Per Cederqvist's avatar
Per Cederqvist committed
105
106
107
extern Success
get_info( Info *result )
{
108
109
    Aux_item_list   filtered;

Per Cederqvist's avatar
Per Cederqvist committed
110
    *result = kom_info;
111
112
113
114
115
    filter_aux_item_list(&result->aux_item_list,
                         &filtered,
                         ACTPERS,
                         ACT_P);
    result->aux_item_list = filtered;
Per Cederqvist's avatar
Per Cederqvist committed
116
117
118
    return OK;
}

119
120
121
122
123
124
125
126
127
128
extern Success
get_version_info( Version_info *result )
{
    /* Allowed before login. */
    result->protocol_version = kom_version_info.protocol_version;
    result->server_name = s_fcrea_str(kom_version_info.server_name);
    result->server_version = s_fcrea_str(kom_version_info.server_version);
    return OK;
}

David Byers's avatar
David Byers committed
129
130
131
132
133
134
135
136
137
138
139
/* /// */
extern Success
set_info(Info *info)
{
    Conference     *conf;
    Text_stat      *text;
    Success         tmp;

    CHK_LOGIN(FAILURE);
    if ( !ENA(admin, 1) )
    {
140
        err_stat = 0;
David Byers's avatar
David Byers committed
141
142
143
144
145
146
	kom_errno = KOM_PERM;
	return FAILURE;
    }

    /* Check that everything mentioned exists */

147
148
149
150
151
    if (info->motd_of_lyskom != 0)
    {
	GET_T_STAT(text, info->motd_of_lyskom, FAILURE);
    }

David Byers's avatar
David Byers committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    GET_C_STAT(conf, info->conf_pres_conf, FAILURE);
    GET_C_STAT(conf, info->pers_pres_conf, FAILURE);
    GET_C_STAT(conf, info->motd_conf, FAILURE);
    GET_C_STAT(conf, info->kom_news_conf, FAILURE);

    if ((tmp = set_motd_of_lyskom(info->motd_of_lyskom)) != OK)
        return tmp;

    kom_info.conf_pres_conf = info->conf_pres_conf;
    kom_info.pers_pres_conf = info->pers_pres_conf;
    kom_info.motd_conf = info->motd_conf;
    kom_info.kom_news_conf = info->kom_news_conf;

    return OK;
}

Per Cederqvist's avatar
Per Cederqvist committed
168
169
170
171
172
173
174
175
176
177
178
/* /// */
extern Success
set_motd_of_lyskom (Text_no motd)
{
    Text_stat *old_motd = NULL;
    Text_stat *new_motd = NULL;

    CHK_LOGIN(FAILURE);

    if ( !ENA(admin, 1) )
    {
179
        err_stat = 0;
Per Cederqvist's avatar
Per Cederqvist committed
180
181
182
183
184
185
186
187
188
	kom_errno = KOM_PERM;
	return FAILURE;
    }
    
    /* Check that the new motd exists before deleting the old*/

    if ( motd != 0 )
    {
	GET_T_STAT(new_motd, motd, FAILURE);
189
	if ( new_motd->no_of_marks >= param.max_marks_text )
Per Cederqvist's avatar
Per Cederqvist committed
190
	{
David Byers's avatar
David Byers committed
191
	    kom_log("LIMIT: set_motd_of_lyskom(%lu): New motd has %d marks.\n",
192
		(unsigned long)motd, new_motd->no_of_marks);
193
            err_stat = motd;
194
	    kom_errno = KOM_MARK_LIMIT;
Per Cederqvist's avatar
Per Cederqvist committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
	    return FAILURE;
	}
    }
    
    /* Unmark the previous motd if it exists. */

    if ( kom_info.motd_of_lyskom != 0
	&& (old_motd = cached_get_text_stat(kom_info.motd_of_lyskom)) != NULL)
    {
	if ( old_motd->no_of_marks > 0 )
	{
	    --old_motd->no_of_marks;
	    mark_text_as_changed( kom_info.motd_of_lyskom );
	}
	else
	{
David Byers's avatar
David Byers committed
211
	    kom_log("ERROR: do_set_motd(): Old motd not marked\n");
Per Cederqvist's avatar
Per Cederqvist committed
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
	}
    }

    /* Mark the new motd */

    if ( motd != 0 )
    {
	++new_motd->no_of_marks;
	mark_text_as_changed( motd );
    }
    
    kom_info.motd_of_lyskom = motd;

    return OK;
}




/*
 * Force all clients to read a message.
 * Sends an asynchronous message. This is obsoleted by send_message.
 */
extern Success
236
broadcast (const String message)
Per Cederqvist's avatar
Per Cederqvist committed
237
{
238
    return send_message(0, message);
Per Cederqvist's avatar
Per Cederqvist committed
239
240
241
242
243
244
}

/*
 * Send a message
 */
extern Success
245
send_message (Conf_no recipient,
Per Cederqvist's avatar
Per Cederqvist committed
246
247
	      const String message)
{
248
249
250
251
252
    Conference *conf_c;
    unsigned short end;
    unsigned short ix;
    Success retval;

Per Cederqvist's avatar
Per Cederqvist committed
253
254
    CHK_LOGIN(FAILURE);

David Byers's avatar
David Byers committed
255
256
    /* Check that the message is not too long */

257
    if (s_strlen(message) > param.broadcast_len)
258
    {
259
        err_stat = param.broadcast_len;
260
261
262
263
	kom_errno = KOM_LONG_STR;
	return FAILURE;
    }

David Byers's avatar
David Byers committed
264
265
266
    /* If the recipient is not everyone, send it to all members */

    if (recipient != 0)
267
    {
David Byers's avatar
David Byers committed
268
269
270
271
272
273
274
275
276
277
278
279
        GET_C_STAT(conf_c, recipient, FAILURE);

        /* Check that the conference is not secret */

        if (access_perm(recipient, conf_c, ACTPERS, ACT_P) <= none)
        {
            err_stat = recipient;
            kom_errno = KOM_UNDEF_CONF;
            return FAILURE;
        }
        
        /* Conference is not secret. Traverse its members */
Per Cederqvist's avatar
Per Cederqvist committed
280

281
282
	end = conf_c->members.no_of_members;
	retval = FAILURE;
David Byers's avatar
David Byers committed
283
284
285
        err_stat = 0;
        kom_errno = KOM_MESSAGE_NOT_SENT;
        
286
287
	for (ix = 0; ix < end; ix++)
	{
David Byers's avatar
David Byers committed
288
289
            /* Don't send messages to passive members */

290
291
292
            if (conf_c->members.members[ix].type.passive)
                continue;

David Byers's avatar
David Byers committed
293
294
            /* Send message to appropriate sessions */

295
	    if (async_send_group_message(conf_c->members.members[ix].member,
296
297
298
299
					 recipient,
                                         ACTPERS,
                                         message,
                                         ENA(admin, 1)) == OK) 
300
301
302
303
304
	    {
		retval = OK;
	    }
	}
    }
David Byers's avatar
David Byers committed
305
306
307
308
309
310
311
312
313
    else
    {
        /* Attempting to broadcast */

        retval =  async_send_message(recipient, ACTPERS,
                                     message, ENA(admin, 1));
    }

    return retval;
314
}
Per Cederqvist's avatar
Per Cederqvist committed
315
316
317
318
319
320


/*
 * Make LysKOM sync its files.
 */
extern Success
Per Cederqvist's avatar
Per Cederqvist committed
321
sync_kom (void) 
Per Cederqvist's avatar
Per Cederqvist committed
322
{
David Byers's avatar
David Byers committed
323
324
325
326
327
    if (!param.permissive_sync)
    {
        CHK_LOGIN(FAILURE);
        if ( !ENA(admin, 1) )
        {
328
            err_stat = 0;
David Byers's avatar
David Byers committed
329
330
331
332
333
            kom_errno = KOM_PERM;
            return FAILURE;
        }
    }

Per Cederqvist's avatar
Per Cederqvist committed
334
335
336
337
338
339
340
341
342
    cache_sync_all();
    dump_statistics();
    return OK;
}

/*
 * Close LysKOM. exit_val is (currently) not used. The database is synced.
 */
extern Success
343
shutdown_kom (int UNUSED(exit_val))
Per Cederqvist's avatar
Per Cederqvist committed
344
{
345
346
347
348
    char *name;
    char *user;
    char *host;

Per Cederqvist's avatar
Per Cederqvist committed
349
350
351
    CHK_LOGIN(FAILURE);
    if ( !ENA(admin, 1) )
    {
352
        err_stat = 0;
Per Cederqvist's avatar
Per Cederqvist committed
353
354
355
356
	kom_errno = KOM_PERM;
	return FAILURE;
    }

357
358
359
    name = s_crea_c_str (active_connection->username);
    user = s_crea_c_str (active_connection->ident_user);
    host = s_crea_c_str (active_connection->hostname);
David Byers's avatar
David Byers committed
360
    kom_log("shutdown initiated by person %d (%s) via %s@%s.\n", 
361
362
363
364
365
	 ACTPERS, name, user, host);
    string_free(host);
    string_free(user);
    string_free(name);
    
366
    go_and_die = 1;
Per Cederqvist's avatar
Per Cederqvist committed
367
368
    return OK;
}
369
370
371
372
373
374
375
376
377
378
379
380
381

extern Success
modify_server_info(Number_list      *items_to_delete,
                   Aux_item_list    *items_to_add)
{
    CHK_LOGIN(FAILURE);
    if ( !ENA(admin, 1) )
    {
        err_stat = 0;
	kom_errno = KOM_PERM;
	return FAILURE;
    }

382
    prepare_aux_item_list(items_to_add, ACTPERS);
383
384
385
386

    if (check_delete_aux_item_list(items_to_delete,
                                   &kom_info.aux_item_list)!=OK)
        return FAILURE;
387
388
    delete_aux_item_list(items_to_delete,
                         &kom_info.aux_item_list,
David Byers's avatar
David Byers committed
389
                         INFO_OBJECT_TYPE,
390
                         0, NULL);
391
392
393

    if (system_check_add_aux_item_list(&kom_info, items_to_add, ACTPERS) != OK)
    {
394
        undelete_aux_item_list(items_to_delete, &kom_info.aux_item_list,
David Byers's avatar
David Byers committed
395
                                   INFO_OBJECT_TYPE,
396
                                   0, NULL);
397
398
399
400
        return FAILURE;
    }

    system_add_aux_item_list(&kom_info, items_to_add, ACTPERS);
David Byers's avatar
David Byers committed
401
    commit_aux_item_list(&kom_info.aux_item_list);
402
403
404
405
406
407
408
409
410
411
412
413
414

    return OK;
}



extern Success
get_collate_table (String * result)
{
    result->string = DEFAULT_COLLAT_TAB;
    result->len = COLLAT_TAB_SIZE;
    return OK;
}