+\f/*
+** GETCTLUSER -- return controlling user if mailing to prog or file
+**
+** Check for a "|" or "/" at the beginning of the address. If
+** found, return a controlling username.
+**
+** Parameters:
+** a - the address to check out
+**
+** Returns:
+** Either NULL, if we werent mailing to a program or file,
+** or a controlling user name (possibly in getpwuid's
+** static buffer).
+**
+** Side Effects:
+** none.
+*/
+
+char *
+getctluser(a)
+ ADDRESS *a;
+{
+ extern ADDRESS *getctladdr();
+ struct passwd *pw;
+ char *retstr;
+
+ /*
+ ** Get unquoted user for file, program or user.name check.
+ ** N.B. remove this code block to always emit controlling
+ ** addresses (at the expense of backward compatibility).
+ */
+
+ {
+ char buf[MAXNAME];
+ (void) strncpy(buf, a->q_paddr, MAXNAME);
+ buf[MAXNAME-1] = '\0';
+ stripquotes(buf, TRUE);
+
+ if (buf[0] != '|' && buf[0] != '/')
+ return((char *)NULL);
+ }
+
+ a = getctladdr(a); /* find controlling address */
+
+ if (a != NULL && a->q_uid != 0 && (pw = getpwuid(a->q_uid)) != NULL)
+ retstr = pw->pw_name;
+ else /* use default user */
+ retstr = DefUser;
+
+ if (tTd(40, 5))
+ printf("Set controlling user for `%s' to `%s'\n",
+ (a == NULL)? "<null>": a->q_paddr, retstr);
+
+ return(retstr);
+}
+\f/*
+** SETCTLUSER - sets `CtlUser' to controlling user
+** CLRCTLUSER - clears controlling user (no params, nothing returned)
+**
+** These routines manipulate `CtlUser'.
+**
+** Parameters:
+** str - controlling user as passed to setctluser()
+**
+** Returns:
+** None.
+**
+** Side Effects:
+** `CtlUser' is changed.
+*/
+
+static char CtlUser[MAXNAME];
+
+setctluser(str)
+register char *str;
+{
+ (void) strncpy(CtlUser, str, MAXNAME);
+ CtlUser[MAXNAME-1] = '\0';
+}
+
+clrctluser()
+{
+ CtlUser[0] = '\0';
+}
+
+\f/*
+** SETCTLADDR -- create a controlling address
+**
+** If global variable `CtlUser' is set and we are given a valid
+** address, make that address a controlling address; change the
+** `q_uid', `q_gid', and `q_ruser' fields and set QGOODUID.
+**
+** Parameters:
+** a - address for which control uid/gid info may apply
+**
+** Returns:
+** None.
+**
+** Side Effects:
+** Fills in uid/gid fields in address and sets QGOODUID
+** flag if appropriate.
+*/
+
+setctladdr(a)
+ ADDRESS *a;
+{
+ struct passwd *pw;
+
+ /*
+ ** If there is no current controlling user, or we were passed a
+ ** NULL addr ptr or we already have a controlling user, return.
+ */
+
+ if (CtlUser[0] == '\0' || a == NULL || a->q_ruser)
+ return;
+
+ /*
+ ** Set up addr fields for controlling user. If `CtlUser' is no
+ ** longer valid, use the default user/group.
+ */
+
+ if ((pw = getpwnam(CtlUser)) != NULL)
+ {
+ if (a->q_home)
+ free(a->q_home);
+ a->q_home = newstr(pw->pw_dir);
+ a->q_uid = pw->pw_uid;
+ a->q_gid = pw->pw_gid;
+ a->q_ruser = newstr(CtlUser);
+ }
+ else
+ {
+ a->q_uid = DefUid;
+ a->q_gid = DefGid;
+ a->q_ruser = newstr(DefUser);
+ }
+
+ a->q_flags |= QGOODUID; /* flag as a "ctladdr" */
+
+ if (tTd(40, 5))
+ printf("Restored controlling user for `%s' to `%s'\n",
+ a->q_paddr, a->q_ruser);
+}