]> andersk Git - moira.git/blame - clients/moira/pobox.c
we need to include mrclient.h now.
[moira.git] / clients / moira / pobox.c
CommitLineData
c441a31a 1/* $Id$
7ac48069 2 *
3 * This is the file pobox.c for the Moira Client, which allows users
59ec8dae 4 * to quickly and easily maintain most parts of the Moira database.
0a2c64cb 5 * It Contains: Functions for handling the poboxes.
5eaef520 6 *
0a2c64cb 7 * Created: 7/10/88
8 * By: Chris D. Peterson
73c83e3d 9 *
7ac48069 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>.
73c83e3d 13 */
14
7ac48069 15#include <mit-copyright.h>
8defc06b 16#include <moira.h>
17#include <moira_site.h>
1bf73297 18#include <mrclient.h>
0a2c64cb 19#include "defs.h"
20#include "f_defs.h"
73c83e3d 21#include "globals.h"
73c83e3d 22
7ac48069 23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27RCSID("$Header$");
28
73c83e3d 29/* Function Name: PrintPOBox
30 * Description: Yet another specialized print function.
31 * Arguments: info - all info about this PO_box.
8defc06b 32 * Returns: MR_CONT
73c83e3d 33 */
34
5eaef520 35static void PrintPOBox(char **info)
73c83e3d 36{
5eaef520 37 char buf[BUFSIZ];
38
979b5f38 39 sprintf(buf, "User: %-10s Box: %-35s Type: %s", info[PO_NAME],
5eaef520 40 info[PO_BOX], info[PO_TYPE]);
41 Put_message(buf);
979b5f38 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 }
73c83e3d 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
5eaef520 62static void RealPrintPOMachines(char **info)
73c83e3d 63{
5eaef520 64 Print(1, info + 1, NULL);
73c83e3d 65}
66
67/* Function Name: PrintPOMachines
68 * Description: Prints all current post offices.
69 * Arguments: none.
0a2c64cb 70 * Returns: SUB_ERROR if the machines could not be printed.
73c83e3d 71 */
72
5eaef520 73static int PrintPOMachines(void)
73c83e3d 74{
44d12d58 75 int status;
5eaef520 76 static char *args[] = {"pop", NULL};
600b459e 77 struct mqelem *top = NULL;
5eaef520 78
79 if ((status = do_mr_query("get_server_locations", CountArgs(args), args,
7ac48069 80 StoreInfo, &top)))
5eaef520 81 {
82 com_err(program_name, status, " in get_server_locations.");
83 return SUB_ERROR;
0a2c64cb 84 }
5eaef520 85
86 top = QueueTop(top);
87 Loop(top, RealPrintPOMachines);
88 FreeQueue(top);
89 return SUB_NORMAL;
73c83e3d 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
5eaef520 98int GetUserPOBox(int argc, char **argv)
73c83e3d 99{
44d12d58 100 int status;
600b459e 101 struct mqelem *top = NULL;
5eaef520 102 char buf[BUFSIZ];
103
104 if (!ValidName(argv[1]))
105 return DM_NORMAL;
106
7ac48069 107 switch ((status = do_mr_query("get_pobox", 1, argv + 1, StoreInfo, &top)))
5eaef520 108 {
8defc06b 109 case MR_NO_MATCH:
5eaef520 110 Put_message("This user has no P.O. Box.");
111 break;
8defc06b 112 case MR_SUCCESS:
5eaef520 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;
73c83e3d 119 default:
5eaef520 120 com_err(program_name, status, " in get_pobox.");
73c83e3d 121 }
5eaef520 122 return DM_NORMAL;
73c83e3d 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.
0a2c64cb 128 * Returns: machine - name of the machine for then new pop box, or NULL.
73c83e3d 129 */
130
5eaef520 131static char *GetNewLocalPOBox(char *local_user)
73c83e3d 132{
5eaef520 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;
7ac48069 144 return canonicalize_hostname(strdup(temp_buf));
0a2c64cb 145 }
5eaef520 146 Put_message("Could not get machines to choose from, quitting.");
147 return (char *) SUB_ERROR;
73c83e3d 148}
149
28f51a24 150static int InsertSortedImapPart(int argc, char **argv, void *arg)
151{
5ac2ad94 152 struct mqelem *new = NULL;
153 struct mqelem *elem, *prev, **parts = arg;
28f51a24 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;
ad386a73 209 struct mqelem *elem = NULL, *servers = NULL, *partitions = NULL;
28f51a24 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;
5ac2ad94 337 elem = elem->q_forw;
28f51a24 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
73c83e3d 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
5eaef520 396int SetUserPOBox(int argc, char **argv)
73c83e3d 397{
44d12d58 398 int status;
1bf73297 399 char *type, temp_buf[BUFSIZ], *local_user, *args[10], *box;
600b459e 400 struct mqelem *top = NULL;
5eaef520 401
28f51a24 402 local_user = argv[1];
5eaef520 403 if (!ValidName(local_user))
404 return DM_NORMAL;
405
406 /* Print the current PO Box info */
7ac48069 407 switch ((status = do_mr_query("get_pobox", 1, argv + 1, StoreInfo, &top)))
5eaef520 408 {
2f25313c 409 case MR_SUCCESS:
5eaef520 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;
2f25313c 416 case MR_NO_MATCH:
5eaef520 417 Put_message("This user has no P.O. Box.");
418 break;
2f25313c 419 default:
5eaef520 420 com_err(program_name, status, " in get_pobox.");
421 return DM_NORMAL;
2f25313c 422 }
423
28f51a24 424 Put_message("");
425
5eaef520 426 sprintf(temp_buf, "Assign %s a local PO Box (y/n)", local_user);
427 switch (YesNoQuestion(temp_buf, TRUE))
428 {
73c83e3d 429 case TRUE:
5eaef520 430 switch (YesNoQuestion("Use Previous Local Box (y/n)", TRUE))
431 {
73c83e3d 432 case TRUE:
5eaef520 433 switch ((status = do_mr_query("set_pobox_pop", 1,
7ac48069 434 &local_user, NULL, NULL)))
5eaef520 435 {
8defc06b 436 case MR_SUCCESS:
5eaef520 437 return DM_NORMAL;
8defc06b 438 case MR_MACHINE:
5eaef520 439 sprintf(temp_buf, "%s did not have a previous local PO Box.",
440 local_user);
441 Put_message(temp_buf);
73c83e3d 442 default:
5eaef520 443 com_err(program_name, status, " in set_pobox_pop.");
444 return DM_NORMAL;
73c83e3d 445 }
28f51a24 446 /* Fall through from MR_MACHINE case. */
73c83e3d 447 case FALSE:
a41a1a03 448 type = strdup("IMAP");
28f51a24 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";
73a65411 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 }
28f51a24 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 }
5eaef520 486 break;
73c83e3d 487 default:
5eaef520 488 return DM_NORMAL;
73c83e3d 489 }
5eaef520 490 break;
73c83e3d 491 case FALSE:
28f51a24 492 type = "SMTP";
5eaef520 493 sprintf(temp_buf, "Set up a foreign PO Box for %s (y/n)", local_user);
494 switch (YesNoQuestion(temp_buf, TRUE))
495 {
73c83e3d 496 case TRUE:
1bf73297 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)
5eaef520 501 return DM_NORMAL;
502 break;
73c83e3d 503 case FALSE:
504 default:
5eaef520 505 return DM_NORMAL; /* ^C hit. */
73c83e3d 506 }
5eaef520 507 break;
73c83e3d 508 default: /* ^C hit. */
5eaef520 509 Put_message("Aborted.");
510 return DM_NORMAL;
73c83e3d 511 }
6f368c99 512
5eaef520 513 args[PO_NAME] = local_user;
514 args[PO_TYPE] = type;
515 args[PO_BOX] = box;
abe26090 516 args[3] = NULL;
5eaef520 517 if ((status = do_mr_query("set_pobox", CountArgs(args), args,
7ac48069 518 NULL, NULL)))
5eaef520 519 com_err(program_name, status, " in ChangeUserPOBox");
520 else
521 Put_message("PO Box assigned.");
1bf73297 522 free(box);
5eaef520 523
524 return DM_NORMAL;
73c83e3d 525}
526
450849e9 527/* Function Name: SplitUserPOBox
528 * Description: Splits the user's PO Box between local and SMTP
529 * Arguments: argc, argv - name of user in argv[1].
530 * Returns: DM_NORMAL.
531 */
532
533int SplitUserPOBox(int argc, char **argv)
534{
535 char temp_buf[BUFSIZ], *args[3], *box;
536 int status;
537
538 if (!ValidName(argv[1]))
539 return DM_NORMAL;
540
541 if (!Prompt_input("Foreign PO Box for this user? ", temp_buf, BUFSIZ))
542 return DM_NORMAL;
543 if (mrcl_validate_pobox_smtp(argv[1], temp_buf, &box) !=
544 MRCL_SUCCESS)
545 return DM_NORMAL;
546
547 args[0] = argv[1];
548 args[1] = "SPLIT";
549 args[2] = box;
550
551 status = do_mr_query("set_pobox", 3, args, NULL, NULL);
552 if (status == MR_MACHINE)
553 Put_message("User has no local PO Box--PO Box unchanged.");
554 else if (status)
555 com_err(program_name, status, " in SplitUserPOBox");
556 else
557 Put_message("PO Box split.");
558 free(box);
559
560 return DM_NORMAL;
561}
562
73c83e3d 563/* Function Name: RemoveUserPOBox
564 * Description: Removes this users POBox.
565 * Arguments: argc, argv - name of user in argv[1].
566 * Returns: DM_NORMAL.
567 */
568
5eaef520 569int RemoveUserPOBox(int argc, char **argv)
73c83e3d 570{
44d12d58 571 int status;
5eaef520 572 char temp_buf[BUFSIZ];
573
574 if (!ValidName(argv[1]))
575 return DM_NORMAL;
576
577 sprintf(temp_buf, "Are you sure that you want to remove %s's PO Box (y/n)",
578 argv[1]);
579
580 if (Confirm(temp_buf))
581 {
582 if ((status = do_mr_query("delete_pobox", 1, argv + 1,
7ac48069 583 NULL, NULL)))
5eaef520 584 com_err(program_name, status, " in delete_pobox.");
585 else
586 Put_message("PO Box removed.");
73c83e3d 587 }
5eaef520 588 return DM_NORMAL;
73c83e3d 589}
This page took 0.204349 seconds and 5 git commands to generate.