]> andersk Git - moira.git/blame_incremental - clients/moira/pobox.c
First cut at support for winhomedir and winprofiledir support.
[moira.git] / clients / moira / pobox.c
... / ...
CommitLineData
1/* $Id$
2 *
3 * This is the file pobox.c for the Moira Client, which allows users
4 * to quickly and easily maintain most parts of the Moira database.
5 * It Contains: Functions for handling the poboxes.
6 *
7 * Created: 7/10/88
8 * By: Chris D. Peterson
9 *
10 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
11 * For copying and distribution information, please see the file
12 * <mit-copyright.h>.
13 */
14
15#include <mit-copyright.h>
16#include <moira.h>
17#include <moira_site.h>
18#include <mrclient.h>
19#include "defs.h"
20#include "f_defs.h"
21#include "globals.h"
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27RCSID("$Header$");
28
29/* Function Name: PrintPOBox
30 * Description: Yet another specialized print function.
31 * Arguments: info - all info about this PO_box.
32 * Returns: MR_CONT
33 */
34
35static void PrintPOBox(char **info)
36{
37 char buf[BUFSIZ];
38
39 sprintf(buf, "User: %-10s Box: %-35s Type: %s", info[PO_NAME],
40 info[PO_BOX], info[PO_TYPE]);
41 Put_message(buf);
42 if (info[6])
43 {
44 sprintf(buf, "Address: %s", info[PO_ADDR]);
45 Put_message(buf);
46 sprintf(buf, MOD_FORMAT, info[5], info[4], info[6]);
47 Put_message(buf);
48 }
49 else
50 {
51 sprintf(buf, MOD_FORMAT, info[4], info[3], info[5]);
52 Put_message(buf);
53 }
54}
55
56/* Function Name: RealPrintPOMachines
57 * Description: Actually does the printing for PrintPOMachines.
58 * Arguments: info, - name of machines in info[1].
59 * Returns: none.
60 */
61
62static void RealPrintPOMachines(char **info)
63{
64 Print(1, info + 1, NULL);
65}
66
67/* Function Name: PrintPOMachines
68 * Description: Prints all current post offices.
69 * Arguments: none.
70 * Returns: SUB_ERROR if the machines could not be printed.
71 */
72
73static int PrintPOMachines(void)
74{
75 int status;
76 static char *args[] = {"pop", NULL};
77 struct mqelem *top = NULL;
78
79 if ((status = do_mr_query("get_server_locations", CountArgs(args), args,
80 StoreInfo, &top)))
81 {
82 com_err(program_name, status, " in get_server_locations.");
83 return SUB_ERROR;
84 }
85
86 top = QueueTop(top);
87 Loop(top, RealPrintPOMachines);
88 FreeQueue(top);
89 return SUB_NORMAL;
90}
91
92/* Function Name: GetUserPOBox
93 * Description: prints the users POBox information.
94 * Arguments: argc, argv - name of the user in argv[1].
95 * Returns: DM_NORMAL.
96 */
97
98int GetUserPOBox(int argc, char **argv)
99{
100 int status;
101 struct mqelem *top = NULL;
102 char buf[BUFSIZ];
103
104 if (!ValidName(argv[1]))
105 return DM_NORMAL;
106
107 switch ((status = do_mr_query("get_pobox", 1, argv + 1, StoreInfo, &top)))
108 {
109 case MR_NO_MATCH:
110 Put_message("This user has no P.O. Box.");
111 break;
112 case MR_SUCCESS:
113 sprintf(buf, "Current pobox for user %s: \n", argv[1]);
114 Put_message("");
115 top = QueueTop(top);
116 Loop(top, PrintPOBox); /* should only return 1 box. */
117 FreeQueue(top);
118 break;
119 default:
120 com_err(program_name, status, " in get_pobox.");
121 }
122 return DM_NORMAL;
123}
124
125/* Function Name: GetNewLocalPOBox
126 * Description: get the machine for a new local pop Box for the user.
127 * Arguments: local_user - name of the local user.
128 * Returns: machine - name of the machine for then new pop box, or NULL.
129 */
130
131static char *GetNewLocalPOBox(char *local_user)
132{
133 char temp_buf[BUFSIZ];
134
135 sprintf(temp_buf, "%s %s", "Pick one of the following",
136 "machines for this user's Post Office.");
137 Put_message(temp_buf);
138 Put_message("");
139 if (PrintPOMachines() == SUB_NORMAL)
140 {
141 Put_message("");
142 if (!Prompt_input("Which Machine? ", temp_buf, BUFSIZ))
143 return (char *) SUB_ERROR;
144 return canonicalize_hostname(strdup(temp_buf));
145 }
146 Put_message("Could not get machines to choose from, quitting.");
147 return (char *) SUB_ERROR;
148}
149
150static int InsertSortedImapPart(int argc, char **argv, void *arg)
151{
152 struct mqelem *new = NULL;
153 struct mqelem *elem, *prev, **parts = arg;
154 int avail = atoi(argv[NFS_SIZE]) - atoi(argv[NFS_ALLOC]);
155
156 /* Dup the argv into a new mqelem. */
157 StoreInfo(argc, argv, &new);
158
159 if (!*parts)
160 {
161 *parts = new;
162 return MR_CONT;
163 }
164
165 /* Find the right place in parts for it. */
166 elem = *parts;
167 prev = NULL;
168 while (elem)
169 {
170 char **xargv = elem->q_data;
171 if (atoi(xargv[NFS_SIZE]) - atoi(xargv[NFS_ALLOC]) < avail)
172 break;
173 prev = elem;
174 elem = elem->q_forw;
175 }
176
177 if (prev)
178 AddQueue(new, prev);
179 else
180 {
181 new->q_forw = *parts;
182 (*parts)->q_back = new;
183 *parts = new;
184 }
185
186 return MR_CONT;
187}
188
189static int AddImapPartitions(char *server, struct mqelem **parts)
190{
191 char *argv[2];
192 int status;
193
194 argv[0] = server;
195 argv[1] = "*";
196
197 status = do_mr_query("get_nfsphys", 2, argv, InsertSortedImapPart, parts);
198 if (status)
199 {
200 com_err(program_name, status, " in AddImapPartitions");
201 return SUB_ERROR;
202 }
203 return SUB_NORMAL;
204}
205
206char *CreateImapBox(char *user)
207{
208 int status;
209 struct mqelem *elem = NULL, *servers = NULL, *partitions = NULL;
210 char *server = NULL, *partition = NULL;
211 char *argv[11], *fsname, temp_buf[BUFSIZ];
212 static char *default_imap_quota = NULL;
213
214 if (!default_imap_quota)
215 {
216 char **vargv;
217 argv[0] = "def_imap_quota";
218 status = do_mr_query("get_value", 1, argv, StoreInfo, &elem);
219 if (status)
220 {
221 com_err(program_name, status, " getting default IMAP quota");
222 return (char *)SUB_ERROR;
223 }
224 vargv = elem->q_data;
225 default_imap_quota = strdup(vargv[0]);
226 FreeQueue(elem);
227 }
228
229 argv[0] = "POSTOFFICE";
230 status = do_mr_query("get_server_locations", 1, argv, StoreInfo, &servers);
231 if (status)
232 {
233 com_err(program_name, status, " in GetImapBox.");
234 return (char *)SUB_ERROR;
235 }
236 servers = QueueTop(servers);
237
238 /* Get an IMAP server. */
239 while (!server)
240 {
241 server = strdup("[ANY]");
242 if (GetValueFromUser("IMAP Server? ['?' for a list]", &server) !=
243 SUB_NORMAL)
244 {
245 free(server);
246 FreeQueue(servers);
247 return (char *)SUB_ERROR;
248 }
249
250 if (!strcmp(server, "?"))
251 {
252 elem = servers;
253 while (elem)
254 {
255 char **sargv = elem->q_data;
256 sprintf(temp_buf, " %s\n", sargv[1]);
257 Put_message(temp_buf);
258 elem = elem->q_forw;
259 }
260 free(server);
261 server = NULL;
262 }
263 }
264 server = canonicalize_hostname(server);
265
266 /* Get the partitions on that server. */
267 if (!strcasecmp(server, "[ANY]"))
268 {
269 char **sargv;
270
271 elem = servers;
272 while (elem && !status)
273 {
274 sargv = elem->q_data;
275 status = AddImapPartitions(sargv[1], &partitions);
276 elem = elem->q_forw;
277 }
278
279 if (partitions)
280 {
281 sargv = partitions->q_data;
282 server = strdup(sargv[NFS_NAME]);
283 partition = strdup(sargv[NFS_DIR]);
284 }
285 }
286 else
287 status = AddImapPartitions(server, &partitions);
288 partitions = QueueTop(partitions);
289
290 FreeQueue(servers);
291 if (status || !partitions)
292 {
293 if (!partitions)
294 com_err(program_name, 0, "No registered nfsphys on %s.", server);
295 else
296 FreeQueue(partitions);
297 free(server);
298 return (char *)SUB_ERROR;
299 }
300
301 /* Pick a partition */
302 while (!partition)
303 {
304 char **pargv = partitions->q_data;
305 partition = strdup(pargv[NFS_DIR]);
306 if (GetValueFromUser("Partition? ['?' for a list]", &partition) !=
307 SUB_NORMAL)
308 {
309 free(server);
310 free(partition);
311 FreeQueue(partitions);
312 return (char *)SUB_ERROR;
313 }
314
315 elem = partitions;
316 if (!strcmp(partition, "?"))
317 {
318 while (elem)
319 {
320 char **pargv = elem->q_data;
321 sprintf(temp_buf, " %s (%s available, %d free)",
322 pargv[NFS_DIR], pargv[NFS_SIZE],
323 atoi(pargv[NFS_SIZE]) - atoi(pargv[NFS_ALLOC]));
324 Put_message(temp_buf);
325 elem = elem->q_forw;
326 }
327 free(partition);
328 partition = NULL;
329 }
330 else
331 {
332 while (elem)
333 {
334 char **pargv = elem->q_data;
335 if (!strcmp(partition, pargv[NFS_DIR]))
336 break;
337 elem = elem->q_forw;
338 }
339 if (!elem)
340 {
341 com_err(program_name, 0, "No such partition %s", partition);
342 free(partition);
343 partition = NULL;
344 }
345 }
346 }
347 FreeQueue(partitions);
348
349 fsname = malloc(strlen(user) + 4);
350 sprintf(fsname, "%s.po", user);
351 argv[FS_NAME] = fsname;
352 argv[FS_TYPE] = "IMAP";
353 argv[FS_MACHINE] = server;
354 argv[FS_PACK] = partition;
355 argv[FS_M_POINT] = "";
356 argv[FS_ACCESS] = "w";
357 argv[FS_COMMENTS] = "IMAP box";
358 argv[FS_OWNER] = user;
359 argv[FS_OWNERS] = "wheel";
360 argv[FS_CREATE] = "1";
361 argv[FS_L_TYPE] = "USER";
362
363 status = do_mr_query("add_filesys", 11, argv, NULL, NULL);
364 free(server);
365 free(partition);
366
367 if (status)
368 {
369 com_err(program_name, status, " creating IMAP filesys in CreateImapBox");
370 free(fsname);
371 return (char *)SUB_ERROR;
372 }
373
374 argv[Q_FILESYS] = fsname;
375 argv[Q_TYPE] = "USER";
376 argv[Q_NAME] = user;
377 argv[Q_QUOTA] = default_imap_quota;
378
379 status = do_mr_query("add_quota", 4, argv, NULL, NULL);
380 if (status)
381 {
382 com_err(program_name, status, " setting quota in CreateImapBox");
383 free(fsname);
384 return (char *)SUB_ERROR;
385 }
386 else
387 return fsname;
388}
389
390/* Function Name: SetUserPOBox
391 * Description: Addes or Chnages the P.O. Box for a user.
392 * Arguments: argc, argv - the login name of the user in argv[1].
393 * Returns: DM_NORMAL.
394 */
395
396int SetUserPOBox(int argc, char **argv)
397{
398 int status;
399 char *type, temp_buf[BUFSIZ], *local_user, *args[10], *box;
400 struct mqelem *top = NULL;
401
402 local_user = argv[1];
403 if (!ValidName(local_user))
404 return DM_NORMAL;
405
406 /* Print the current PO Box info */
407 switch ((status = do_mr_query("get_pobox", 1, argv + 1, StoreInfo, &top)))
408 {
409 case MR_SUCCESS:
410 sprintf(temp_buf, "Current pobox for user %s: \n", local_user);
411 Put_message("");
412 top = QueueTop(top);
413 Loop(top, PrintPOBox); /* should only return 1 box. */
414 FreeQueue(top);
415 break;
416 case MR_NO_MATCH:
417 Put_message("This user has no P.O. Box.");
418 break;
419 default:
420 com_err(program_name, status, " in get_pobox.");
421 return DM_NORMAL;
422 }
423
424 Put_message("");
425
426 sprintf(temp_buf, "Assign %s a local PO Box (y/n)", local_user);
427 switch (YesNoQuestion(temp_buf, TRUE))
428 {
429 case TRUE:
430 switch (YesNoQuestion("Use Previous Local Box (y/n)", TRUE))
431 {
432 case TRUE:
433 switch ((status = do_mr_query("set_pobox_pop", 1,
434 &local_user, NULL, NULL)))
435 {
436 case MR_SUCCESS:
437 return DM_NORMAL;
438 case MR_MACHINE:
439 sprintf(temp_buf, "%s did not have a previous local PO Box.",
440 local_user);
441 Put_message(temp_buf);
442 default:
443 com_err(program_name, status, " in set_pobox_pop.");
444 return DM_NORMAL;
445 }
446 /* Fall through from MR_MACHINE case. */
447 case FALSE:
448 type = strdup("IMAP");
449 if (GetValueFromUser("Kind of Local PO Box?", &type) == SUB_ERROR)
450 {
451 free(type);
452 return DM_NORMAL;
453 }
454 if (!strcasecmp(type, "POP"))
455 {
456 free(type);
457 type = "POP";
458 if ((box = GetNewLocalPOBox(local_user)) == (char *) SUB_ERROR)
459 return DM_NORMAL;
460 }
461 else if (!strcasecmp(type, "IMAP"))
462 {
463 free(type);
464 type = "IMAP";
465 switch (YesNoQuestion("Create IMAP filesystem (y/n)", TRUE))
466 {
467 case TRUE:
468 if ((box = CreateImapBox(local_user)) == (char *) SUB_ERROR)
469 return DM_NORMAL;
470 break;
471 case FALSE:
472 box = malloc(strlen(local_user) + 4);
473 sprintf(box, "%s.po", local_user);
474 break;
475 default:
476 return DM_NORMAL;
477 }
478 }
479 else
480 {
481 sprintf(temp_buf, "Unknown local PO Box type %s", type);
482 Put_message(temp_buf);
483 free(type);
484 return DM_NORMAL;
485 }
486 break;
487 default:
488 return DM_NORMAL;
489 }
490 break;
491 case FALSE:
492 type = "SMTP";
493 sprintf(temp_buf, "Set up a foreign PO Box for %s (y/n)", local_user);
494 switch (YesNoQuestion(temp_buf, TRUE))
495 {
496 case TRUE:
497 if (!Prompt_input("Foreign PO Box for this user? ", temp_buf, BUFSIZ))
498 return DM_NORMAL;
499 if (mrcl_validate_pobox_smtp(local_user, temp_buf, &box) !=
500 MRCL_SUCCESS)
501 {
502 if (mrcl_get_message())
503 Put_message(mrcl_get_message());
504 return DM_NORMAL;
505 }
506 break;
507 case FALSE:
508 default:
509 return DM_NORMAL; /* ^C hit. */
510 }
511 break;
512 default: /* ^C hit. */
513 Put_message("Aborted.");
514 return DM_NORMAL;
515 }
516
517 args[PO_NAME] = local_user;
518 args[PO_TYPE] = type;
519 args[PO_BOX] = box;
520 args[3] = NULL;
521 if ((status = do_mr_query("set_pobox", CountArgs(args), args,
522 NULL, NULL)))
523 com_err(program_name, status, " in ChangeUserPOBox");
524 else
525 Put_message("PO Box assigned.");
526 free(box);
527
528 return DM_NORMAL;
529}
530
531/* Function Name: SplitUserPOBox
532 * Description: Splits the user's PO Box between local and SMTP
533 * Arguments: argc, argv - name of user in argv[1].
534 * Returns: DM_NORMAL.
535 */
536
537int SplitUserPOBox(int argc, char **argv)
538{
539 char temp_buf[BUFSIZ], *args[3], *box;
540 int status;
541
542 if (!ValidName(argv[1]))
543 return DM_NORMAL;
544
545 if (!Prompt_input("Foreign PO Box for this user? ", temp_buf, BUFSIZ))
546 return DM_NORMAL;
547 if (mrcl_validate_pobox_smtp(argv[1], temp_buf, &box) !=
548 MRCL_SUCCESS)
549 {
550 if (mrcl_get_message())
551 Put_message(mrcl_get_message());
552 return DM_NORMAL;
553 }
554
555 args[0] = argv[1];
556 args[1] = "SPLIT";
557 args[2] = box;
558
559 status = do_mr_query("set_pobox", 3, args, NULL, NULL);
560 if (status == MR_MACHINE)
561 Put_message("User has no local PO Box--PO Box unchanged.");
562 else if (status)
563 com_err(program_name, status, " in SplitUserPOBox");
564 else
565 Put_message("PO Box split.");
566 free(box);
567
568 return DM_NORMAL;
569}
570
571/* Function Name: RemoveUserPOBox
572 * Description: Removes this users POBox.
573 * Arguments: argc, argv - name of user in argv[1].
574 * Returns: DM_NORMAL.
575 */
576
577int RemoveUserPOBox(int argc, char **argv)
578{
579 int status;
580 char temp_buf[BUFSIZ];
581
582 if (!ValidName(argv[1]))
583 return DM_NORMAL;
584
585 sprintf(temp_buf, "Are you sure that you want to remove %s's PO Box (y/n)",
586 argv[1]);
587
588 if (Confirm(temp_buf))
589 {
590 if ((status = do_mr_query("delete_pobox", 1, argv + 1,
591 NULL, NULL)))
592 com_err(program_name, status, " in delete_pobox.");
593 else
594 Put_message("PO Box removed.");
595 }
596 return DM_NORMAL;
597}
This page took 0.059256 seconds and 5 git commands to generate.