int GetUserPOBox(int argc, char **argv);
int SetUserPOBox(int argc, char **argv);
+int SplitUserPOBox(int argc, char **argv);
int RemoveUserPOBox(int argc, char **argv);
/* quota.c */
NULLFUNC,
NULLFUNC,
"Post Office Box Menu",
- 4,
+ 5,
{
{GetUserPOBox, NULLMENU, 2, {
{"show", "Show a user's post office box"},
{"set", "Set (Add or Change) a user's post office box"},
{"login name", "login name: "}
} },
+ {SplitUserPOBox, NULLMENU, 2, {
+ {"split", "Split a user's post office box"},
+ {"login name", "login name: "}
+ } },
{RemoveUserPOBox, NULLMENU, 2, {
{"remove", "Remove a user's post office box"},
{"login name", "login name: "}
return DM_NORMAL;
}
+/* Function Name: SplitUserPOBox
+ * Description: Splits the user's PO Box between local and SMTP
+ * Arguments: argc, argv - name of user in argv[1].
+ * Returns: DM_NORMAL.
+ */
+
+int SplitUserPOBox(int argc, char **argv)
+{
+ char temp_buf[BUFSIZ], *args[3], *box;
+ int status;
+
+ if (!ValidName(argv[1]))
+ return DM_NORMAL;
+
+ if (!Prompt_input("Foreign PO Box for this user? ", temp_buf, BUFSIZ))
+ return DM_NORMAL;
+ if (mrcl_validate_pobox_smtp(argv[1], temp_buf, &box) !=
+ MRCL_SUCCESS)
+ return DM_NORMAL;
+
+ args[0] = argv[1];
+ args[1] = "SPLIT";
+ args[2] = box;
+
+ status = do_mr_query("set_pobox", 3, args, NULL, NULL);
+ if (status == MR_MACHINE)
+ Put_message("User has no local PO Box--PO Box unchanged.");
+ else if (status)
+ com_err(program_name, status, " in SplitUserPOBox");
+ else
+ Put_message("PO Box split.");
+ free(box);
+
+ return DM_NORMAL;
+}
+
/* Function Name: RemoveUserPOBox
* Description: Removes this users POBox.
* Arguments: argc, argv - name of user in argv[1].
*
* chpobox -p restores the pobox to a previous POP/IMAP box, if there was one.
*
+ * chpobox -S address means split mail between POP/IMAP and SMTP
+ *
* chpobox -u [user] is needed if you are logged in as one user, but
* are trying to change the email address of another. You must have
* Kerberos tickets as the person whose address you are trying to
struct passwd *pwd;
char *mrarg[3];
char *address, *uname;
- int c, setflag, prevpop, status;
+ int c, setflag, splitflag, prevflag, status;
- setflag = prevpop = 0;
+ setflag = splitflag = prevflag = 0;
address = uname = NULL;
if ((whoami = strrchr(argv[0], '/')) == NULL)
if (argc > 5)
usage();
- while ((c = getopt(argc, argv, "s:pu:")) != -1)
+ while ((c = getopt(argc, argv, "s:S:pu:")) != -1)
switch (c)
{
case 's':
- if (prevpop)
- usage();
- else
- {
- setflag++;
- address = optarg;
- }
+ setflag++;
+ address = optarg;
+ break;
+
+ case 'S':
+ splitflag++;
+ address = optarg;
break;
+
case 'p':
- if (setflag)
- usage();
- else
- prevpop++;
+ prevflag++;
break;
+
case 'u':
uname = optarg;
break;
+
default:
usage();
break;
if (argc == 2 && optind == 1 && !uname)
uname = argv[optind++];
- if (optind != argc)
+ if (optind != argc || (prevflag + splitflag + setflag > 1))
usage();
if (!uname)
if (mrcl_connect(NULL, "chpobox", 2, 1) != MRCL_SUCCESS)
exit(1);
- if (setflag)
+ if (setflag || splitflag)
{
char *addr;
if (mrcl_validate_pobox_smtp(uname, address, &addr) != MRCL_SUCCESS)
printf("\n");
goto show;
}
- mrarg[1] = "SMTP";
+ mrarg[1] = setflag ? "SMTP" : "SPLIT";
mrarg[2] = addr;
status = mr_query("set_pobox", 3, mrarg, NULL, NULL);
free(addr);
mrarg[0], mrarg[1], mrarg[2]);
}
}
- else if (prevpop)
+ else if (prevflag)
{
status = mr_query("set_pobox_pop", 1, mrarg, NULL, NULL);
if (status == MR_MACHINE)
EXEC SQL OPEN u_cursor;
while (1)
{
+ char *saddr = NULL, *paddr = NULL;
+
EXEC SQL FETCH u_cursor INTO :id, :login, :potype, :pid, :iid, :bid;
if (sqlca.sqlcode)
break;
u = malloc(sizeof(struct user));
u->login = strdup(strtrim(login));
- if (potype[0] == 'I')
- {
- EXEC SQL SELECT f.mach_id INTO :pid FROM filesys f, users u
- WHERE u.users_id = :id AND f.filsys_id = u.imap_id;
- if (sqlca.sqlcode == 0)
- potype[0] = 'P';
- }
- if (potype[0] == 'P' && (s = hash_lookup(machines, pid)))
+ if (!strcmp(strtrim(potype), "NONE"))
+ u->pobox = NULL;
+ else
{
- char *buf = malloc(strlen(u->login) + strlen(s) + 2);
- sprintf(buf, "%s@%s", u->login, s);
- u->pobox = buf;
+ /* If SMTP or SPLIT, get SMTP address. */
+ if (potype[0] == 'S')
+ {
+ saddr = hash_lookup(strings, bid);
+
+ /* If SMTP, clear pid and iid. */
+ if (potype[1] == 'M')
+ pid = iid = 0;
+ }
+
+ /* If IMAP, or SPLIT with IMAP, set pid to mach_id. */
+ if (potype[0] == 'I' || (potype[0] == 'S' && iid))
+ {
+ EXEC SQL SELECT mach_id INTO :pid FROM filesys
+ WHERE filsys_id = :iid;
+ }
+
+ if (pid && (s = hash_lookup(machines, pid)))
+ {
+ paddr = malloc(strlen(u->login) + strlen(s) + 2);
+ sprintf(paddr, "%s@%s", u->login, s);
+ }
+
+ if (paddr && saddr)
+ {
+ u->pobox = malloc(strlen(paddr) + strlen(saddr) + 3);
+ sprintf(u->pobox, "%s, %s", paddr, saddr);
+ free(paddr);
+ }
+ else if (paddr)
+ u->pobox = paddr;
+ else
+ u->pobox = saddr;
}
- else if (potype[0] == 'S')
- u->pobox = hash_lookup(strings, bid);
- else
- u->pobox = NULL;
check_string(u->login);
if (hash_store(users, id, u) < 0)
char *ptype, *p;
int mid, sid, status, i;
EXEC SQL BEGIN DECLARE SECTION;
- int users_id;
+ int users_id, pid, iid, bid;
char mach[MACHINE_NAME_SIZE], fs[FILESYS_LABEL_SIZE];
char str[STRINGS_STRING_SIZE];
EXEC SQL END DECLARE SECTION;
ptype = argv[1];
users_id = atoi(argv[2]);
- if (!strcmp(ptype, "POP"))
+ EXEC SQL SELECT pop_id, imap_id, box_id INTO :pid, :iid, :bid
+ FROM users WHERE users_id = :users_id;
+ if (sqlca.sqlcode)
+ return MR_USER;
+
+ if (ptype[0] == 'S')
+ {
+ /* SMTP or SPLIT */
+ EXEC SQL SELECT string INTO :str FROM strings
+ WHERE string_id = :bid;
+ if (sqlca.sqlcode)
+ return MR_STRING;
+
+ /* If SMTP, don't bother fetching IMAP and POP boxes. */
+ if (ptype[1] == 'M')
+ pid = iid = 0;
+ }
+ if (iid)
{
+ /* IMAP, or SPLIT with IMAP */
+ EXEC SQL SELECT f.label, m.name INTO :fs, :mach
+ FROM filesys f, machine m
+ WHERE f.filsys_id = :iid AND f.mach_id = m.mach_id;
+ if (sqlca.sqlcode)
+ return MR_FILESYS;
+ }
+ if (pid)
+ {
+ /* POP, or SPLIT with POP */
EXEC SQL SELECT m.name INTO :mach FROM machine m, users u
WHERE u.users_id = :users_id AND u.pop_id = m.mach_id;
if (sqlca.sqlcode)
return MR_MACHINE;
- free(argv[2]);
+ }
+
+ free(argv[2]);
+ free(argv[3]);
+
+ /* Now assemble the right answer. */
+ if (!strcmp(ptype, "POP"))
+ {
argv[2] = xstrdup(strtrim(mach));
- free(argv[3]);
argv[3] = xmalloc(strlen(argv[0]) + strlen(argv[2]) + 2);
sprintf(argv[3], "%s@%s", argv[0], argv[2]);
}
else if (!strcmp(ptype, "SMTP"))
{
- EXEC SQL SELECT s.string INTO :str FROM strings s, users u
- WHERE u.users_id = :users_id AND u.box_id = s.string_id;
- if (sqlca.sqlcode)
- return MR_STRING;
- free(argv[2]);
- free(argv[3]);
argv[2] = xstrdup(strtrim(str));
argv[3] = xstrdup(str);
}
else if (!strcmp(ptype, "IMAP"))
{
- EXEC SQL SELECT f.label, m.name INTO :fs, :mach
- FROM filesys f, machine m, users u
- WHERE u.users_id = :users_id AND f.filsys_id = u.imap_id
- AND f.mach_id = m.mach_id;
- if (sqlca.sqlcode)
- return MR_FILESYS;
- free(argv[2]);
argv[2] = xstrdup(strtrim(fs));
- free(argv[3]);
argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) + 2);
sprintf(argv[3], "%s@%s", argv[0], mach);
}
+ else if (!strcmp(ptype, "SPLIT"))
+ {
+ argv[2] = xstrdup(strtrim(str));
+ argv[3] = xmalloc(strlen(argv[0]) + strlen(strtrim(mach)) +
+ strlen(str) + 4);
+ sprintf(argv[3], "%s@%s, %s", argv[0], mach, str);
+ }
else /* ptype == "NONE" */
goto skip;
WHERE users_id = :user;
if (dbms_errno)
return mr_errcode;
- if (!strcmp(strtrim(potype), "POP"))
+ if (!strcmp(strtrim(potype), "POP") ||
+ (!strcmp(strtrim(potype), "SPLIT") && id))
set_pop_usage(id, -1);
if (!strcmp(argv[1], "POP"))
WHERE users_id = :user;
set_pop_usage(id, 1);
}
- else if (!strcmp(argv[1], "SMTP"))
+ else if (!strcmp(argv[1], "SMTP") || !strcmp(argv[1], "SPLIT"))
{
if (strchr(box, '/') || strchr(box, '|'))
return MR_BAD_CHAR;
id = add_string(box);
else if (status)
return status;
- EXEC SQL UPDATE users SET potype = 'SMTP', box_id = :id
+
+ /* If going from SMTP or NONE to SPLIT, make sure we have a valid
+ * POP or IMAP box.
+ */
+ if (!strcmp(potype, "SMTP") || !strcmp(potype, "NONE"))
+ {
+ status = set_pobox_pop(q, argv, cl);
+ if (status)
+ return status;
+ }
+ strlcpy(potype, argv[1], sizeof(potype));
+ EXEC SQL UPDATE users SET potype = :potype, box_id = :id
WHERE users_id = :user;
}
else if (!strcmp(argv[1], "IMAP"))
if (sqlca.sqlerrd[2] == 0)
return MR_MACHINE;
EXEC SQL UPDATE users SET potype = 'POP' WHERE users_id = :id;
- if (strcmp(strtrim(type), "POP"))
+ if (!strcmp(strtrim(type), "POP"))
set_pop_usage(mid, 1);
}
else