|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T a
Length: 21617 (0x5471)
Types: TextFile
Names: »add.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/add.c«
/***************************************************************\
* *
* add.c *
* *
* Routines to add various things, users, groups, classes, etc. *
* *
\***************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <strings.h>
#include <ctype.h>
#include <lastlog.h>
#include "sysdep.h"
#include "macros.h"
#include "mem.h"
#include "gpa.h"
#include "lists.h"
#include "account.h"
#ifdef SENDMAIL
#include "alias.h"
#endif
#include "class.h"
#include "groupmap.h"
#include "job.h"
#include "range.h"
#include "sig.h"
#include "sort.h"
#include "save.h"
#define DAY (4*21600)
#ifdef SENDMAIL
extern struct list AliasList, Aliases;
#endif
extern struct list AccountList, Users, ClassList, Classes, GroupMapList;
extern struct list Groups, RangeList, Ranges, Sigs, SigList, Vigs, Shells;
extern struct list Null_List;
extern int ModBits, validint();
extern addr gethomedir();
extern addr makeusername(), DEF_SHELL;
extern char *crypt(), *mktemp(), *sprintf(), *makepass(), *when();
extern time_t choosedate();
static char *XXXXXX = "/mcpXXXXXX";
static char desc[DESCSIZE+1];
static char *idl[1] = { "exception" };
static char *pwl[3] = { "generate", "none", "unused" };
static char *rnl[1];
static char *mdl[2] = { "exclusive", "shared" };
struct list idlist = { 1, 1, (addr *)idl };
struct list pwlist = { 3, 3, (addr *)pwl };
struct list rnlist = { 1, 1, (addr *)rnl };
struct list mdlist = { 2, 2, (addr *)mdl };
#ifdef SENDMAIL
/*
* Add an alias
*/
addalias(c, v)
int c;
addr *v;
{
struct alias al;
struct account *ac;
addr *addressv;
int cc;
register int i;
if (c > 2) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <name>", (char *)v[0]);
return;
}
if (aliasexists((char *)v[1])) {
err1("%s: alias exists", (char *)v[1]);
return;
}
addressv = get_gpa(257);
GetLine("Addresses: ", 256, &cc, addressv, &Null_List);
critical();
savestr(&al.al_name, (char *)v[1]);
zerolist(&al.al_addresses);
zerolist(&al.al_classes);
zerolist(&al.al_sigs);
zerolist(&al.al_groups);
for (i=0; i < cc; i++) {
strlistadd(&al.al_addresses, (char *)addressv[i]);
ac = getacnam((char *)addressv[i]);
if (ac)
strlistadd(&ac->ac_aliases, (char *)addressv[i]);
}
sort_list(&al.al_addresses, pstrcmp);
strlistadd(&Aliases, (char *)v[1]);
genlistadd(&AliasList, (addr)&al, sizeof (struct alias));
sort_list(&Aliases, pstrcmp);
sort_list(&AliasList, aliascmp);
ModBits |= AL;
puts("added");
non_critical();
return;
}
#endif
/*
* Add a class
*/
addclass(c, v)
int c;
addr *v;
{
struct class cs;
struct stat statbuf;
char tempf[MEDIUM_BUF], errmsg[LONG_BUF];
FILE *f, *fopen();
time_t now, time();
int tries, i, ch;
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if ( c != 2 ) {
err1("usage: %s <class>", (char *)v[0]);
return;
}
if (classexists((char *)v[1])) {
err1("%s: class exists", (char *)v[1]);
return;
}
if (yesno("Should the class expire? ") == 0)
cs.cs_exptime = (time_t) 0;
else {
(void) time(&now);
err("Set the expiration date.");
cs.cs_exptime = choosedate(now);
(void) printf("Ends %s\n", when(cs.cs_exptime));
}
(void) strcpy(tempf, TMPDIR);
(void) strcat(tempf, XXXXXX);
(void) mktemp(tempf);
tries = 0;
edit_it:
tries++;
f = fopen(tempf, "w");
if (f == NULL) {
err1("%s: cannot open (write)", tempf);
return;
}
(void) fprintf(f, "Instructor: \n\n");
(void) fprintf(f, "...\n");
(void) fclose(f);
re_edit:
edit(tempf);
if (stat(tempf, &statbuf) == -1) {
perr(tempf);
if (tries < 5) {
sleep(2);
goto edit_it;
}
else {
err1("%s aborted", (char *)v[0]);
(void) unlink(tempf);
return;
}
}
if (statbuf.st_size > DESCSIZE) {
(void)sprintf(errmsg, "description is %d characters too long",
DESCSIZE - statbuf.st_size);
err(errmsg);
sleep(2);
goto re_edit;
}
critical();
f = fopen(tempf, "r");
if (f == NULL) {
err1("%s: cannot open (read)", tempf);
non_critical();
return;
}
savestr(&cs.cs_name, (char *)v[1]);
i = 0;
while ((ch = getc(f)) != EOF)
desc[i++] = (char) ch;
desc[i] = '\0';
cs.cs_dsize = i;
savestr(&cs.cs_desc, desc);
(void) fclose(f);
#ifdef SENDMAIL
zerolist(&cs.cs_aliases);
#endif
genlistadd(&ClassList, (addr) &cs, sizeof (struct class));
strlistadd(&Classes, cs.cs_name);
sort_list(&ClassList, classcmp);
sort_list(&Classes, pstrcmp);
(void) unlink(tempf);
ModBits |= CS;
puts("added");
non_critical();
return;
}
/*
* Add a group
*/
addgroup(c, v)
int c;
addr *v;
{
struct groupmap gm;
char prompt[SHORT_BUF];
addr *gidv;
int cc, gid;
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <name>", (char *)v[0]);
return;
}
if (groupexists((char *)v[1])) {
err1("%s: group exists", (char *)v[1]);
return;
}
gm.gm_gid = nextgid();
(void) sprintf(prompt, "Gid [%d]: ", gm.gm_gid);
gidv = get_gpa(2);
do {
GetLine(prompt, 1, &cc, gidv, &Null_List);
if (cc) {
if (!validint((char *)*gidv)) {
err1("%s makes no sense to me", (char *)*gidv);
continue;
}
gid = atoi((char *)*gidv);
if (gidexists(gid))
err("that gid is taken");
else {
gm.gm_gid = gid;
break;
}
}
else
break;
} while (clear_gpa(gidv, 2));
critical();
savestr(&gm.gm_name, (char *)v[1]);
savestr(&gm.gm_passwd, "*");
zerolist(&gm.gm_mem);
#ifdef SENDMAIL
zerolist(&gm.gm_aliases);
#endif
genlistadd(&GroupMapList, (addr) &gm, sizeof (struct groupmap));
sort_list(&GroupMapList, gmapcmp);
strlistadd(&Groups, gm.gm_name);
sort_list(&Groups, pstrcmp);
ModBits |= GR;
puts("added");
non_critical();
return;
}
int nextgid()
{
register int i, next = 0;
struct groupmap *gm;
for (i=0; i<GroupMapList.l_count; i++) {
gm = (struct groupmap *) GroupMapList.l_list[i];
if (gm->gm_gid > next)
return next;
/*
* Since gid's may be shared (gag) by two or more group names
* the seemingly obvious next++ actually must be...
*/
next = gm->gm_gid + 1;
}
return next;
}
/*
* Add a range
*/
addrange(c, v)
int c;
addr *v;
{
struct range r, *rg;
char prompt[SHORT_BUF];
addr *fromv, *tov, *modev;
int cc, indx;
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <name>", (char *)v[0]);
return;
}
if (!groupexists((char *)v[1])) {
err1("%s: no such group", (char *)v[1]);
return;
}
(void) strcpy(prompt, "From: ");
fromv = get_gpa(2);
do {
GetLine(prompt, 1, &cc, fromv, &Null_List);
if (cc && !validint((char *)*fromv)) {
cc = 0;
continue;
}
} while (cc == 0 && clear_gpa(fromv, 2));
(void) strcpy(prompt, "To : ");
tov = get_gpa(2);
do {
GetLine(prompt, 1, &cc, tov, &Null_List);
if (cc && !validint((char *)*tov)) {
cc = 0;
continue;
}
} while (cc == 0 && clear_gpa(tov, 2));
(void) strcpy(prompt, "Mode: ");
modev = get_gpa(2);
do {
GetLine(prompt, 1, &cc, modev, &mdlist);
} while (cc == 0 && clear_gpa(modev, 2));
if (eq(*modev, "shared"))
r.rg_mode = RG_SHARED;
else if (eq(*modev, "exclusive"))
r.rg_mode = RG_EXCLUSIVE;
else {
err1("%s: unknown mode", (char *)*modev);
return;
}
r.rg_from = atoi((char *)*fromv);
r.rg_to = atoi((char *)*tov);
for (indx=0; indx < RangeList.l_count; indx++) {
rg = (struct range *) RangeList.l_list[indx];
if (rg->rg_mode == RG_SHARED && r.rg_mode == RG_SHARED)
continue;
if (INRANGE(r.rg_from, rg->rg_from, rg->rg_to)) {
err1("conflicts with range of group %s", rg->rg_name);
return;
}
if (INRANGE(r.rg_to, rg->rg_from, rg->rg_to)) {
err1("conflicts with range of group %s", rg->rg_name);
return;
}
}
critical();
savestr(&r.rg_name, (char *)v[1]);
genlistadd(&RangeList, (addr) &r, sizeof (struct range));
sort_list(&RangeList, rangecmp);
strlistadd(&Ranges, (char *)v[1]);
sort_list(&Ranges, pstrcmp);
ModBits |= RG;
puts("added");
non_critical();
return;
}
/*
* Add a sig
*/
addsig(c, v)
int c;
addr *v;
{
struct sig sg;
struct stat statbuf;
FILE *f, *fopen();
time_t now, time();
int tries, i, ch;
char tempf[SHORT_BUF+1], errmsg[LONG_BUF];
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if ( c != 2 ) {
err1("usage: %s <name>", (char *)v[0]);
return;
}
if (sigexists((char *)v[1])) {
err1("%s: sig exists", (char *)v[1]);
return;
}
if (yesno("Should the sig expire? ") == 0)
sg.sg_exptime = (time_t) 0;
else {
(void) time(&now);
err("Set the expiration date.");
sg.sg_exptime = choosedate(now);
(void) printf("Sig ends %s\n", when(sg.sg_exptime));
}
(void) strcpy(tempf, TMPDIR);
(void) strcat(tempf, XXXXXX);
(void) mktemp(tempf);
tries = 0;
edit_it:
tries++;
f = fopen(tempf, "w");
if (f == NULL) {
err1("%s: cannot open (write)", tempf);
return;
}
(void) fprintf(f, "Guru: \n\n");
(void) fprintf(f, "...\n");
(void) fclose(f);
re_edit:
edit(tempf);
if (stat(tempf, &statbuf) == -1) {
perr(tempf);
if (tries < 5) {
sleep(2);
goto edit_it;
}
else {
err1("%s aborted", (char *)v[0]);
(void) unlink(tempf);
return;
}
}
if (statbuf.st_size > DESCSIZE) {
(void) sprintf(errmsg,
"description is %d characters too long",
DESCSIZE - statbuf.st_size);
err(errmsg);
sleep(2);
goto re_edit;
}
critical();
f = fopen(tempf, "r");
if (f == NULL) {
err1("%s: cannot open (read)", tempf);
non_critical();
return;
}
savestr(&sg.sg_name, (char *)v[1]);
i = 0;
while ((ch = getc(f)) != EOF)
desc[i++] = (char) ch;
desc[i] = '\0';
sg.sg_dsize = i;
savestr(&sg.sg_desc, desc);
(void) fclose(f);
#ifdef SENDMAIL
zerolist(&sg.sg_aliases);
#endif
genlistadd(&SigList, (addr) &sg, sizeof (struct sig));
strlistadd(&Sigs, sg.sg_name);
sort_list(&SigList, sigcmp);
sort_list(&Sigs, pstrcmp);
(void) unlink(tempf);
ModBits |= SG;
puts("added");
non_critical();
return;
}
#ifdef SENDMAIL
addtoalias(c, v)
int c;
addr *v;
{
struct alias *al;
struct account *ac;
addr *addressv;
int cc, added = 0, notes = 0;
register int indx;
if (c > 2) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <alias>", (char *)v[0]);
return;
}
al = getalnam((char *)v[1]);
if (!al) {
err1("%s: no such alias", (char *)v[1]);
return;
}
addressv = get_gpa(65);
GetLine("Addresses: ", 64, &cc, addressv, &Null_List);
if (cc == 0) {
err("no change");
return;
}
critical();
for (indx=0; indx < cc; indx++) {
ac = getacnam((char *)addressv[indx]);
if (ac) {
if (!instrlist(&ac->ac_aliases, (char *)v[1])) {
strlistadd(&ac->ac_aliases, (char *)v[1]);
sort_list(&ac->ac_aliases, pstrcmp);
ModBits |= AC;
}
else {
err1("%s: already in alias", (char *)ac->ac_name);
continue;
}
}
if (!instrlist(&al->al_addresses, (char *)addressv[indx])) {
strlistadd(&al->al_addresses, (char *)addressv[indx]);
added++;
}
else if (!ac)
err1("%s: already in alias", (char *)addressv[indx]);
else {
err1("%s: unique membership noted", (char *)ac->ac_name);
notes++;
}
}
if (added) {
sort_list(&al->al_addresses, pstrcmp);
ModBits |= AL;
(void) printf("%d added\n", added);
}
else if (!notes)
err("no change");
non_critical();
return;
}
#endif
addtoclass(c, v)
int c;
addr *v;
{
struct account *ac;
struct class *cs;
addr *userv;
int cc, added = 0;
register int indx;
#ifdef SENDMAIL
struct alias *al;
register int j;
#endif
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <class>", (char *)v[0]);
return;
}
cs = getcsnam((char *)v[1]);
if (!cs) {
err1("%s: no such class", (char *)v[1]);
return;
}
userv = get_gpa(65);
GetLine("Users: ", 64, &cc, userv, &Users);
if (cc == 0) {
err("no change");
return;
}
critical();
for (indx=0; indx < cc; indx++) {
ac = getacnam((char *)userv[indx]);
if (!ac) {
err1("%s: no such user", (char *)userv[indx]);
continue;
}
if (instrlist(&ac->ac_classes, (char *)v[1])) {
err1("%s: already is in class\n",
(char *)userv[indx]);
continue;
}
strlistadd(&ac->ac_classes, (char *)v[1]);
sort_list(&ac->ac_classes, pstrcmp);
#ifdef SENDMAIL
for (j=0; j < cs->cs_aliases.l_count; j++) {
al = getalnam((char *)cs->cs_aliases.l_list[j]);
if (!al) continue; /* trouble */
if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) {
strlistadd(&al->al_addresses, (char *)ac->ac_name);
sort_list(&al->al_addresses, pstrcmp);
ModBits |= AL;
}
}
#endif
added++;
}
if (added) {
ModBits |= AC;
(void) printf("%d added\n", added);
}
else
err("no change");
non_critical();
return;
}
addtogroup(c, v)
int c;
addr *v;
{
struct account *ac;
struct groupmap *gm;
addr *userv;
int cc, added = 0;
register int indx;
#ifdef SENDMAIL
struct alias *al;
register int j;
#endif
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <group>", (char *)v[0]);
return;
}
gm = getgmnam((char *)v[1]);
if (!gm) {
err1("%s: no such group", (char *)v[1]);
return;
}
userv = get_gpa(65);
GetLine("Users: ", 64, &cc, userv, &Users);
if (cc == 0) {
err("no change");
return;
}
critical();
for (indx=0; indx < cc; indx++) {
if (instrlist(&gm->gm_mem, (char *)userv[indx])) {
err1("%s: is in group", (char *)userv[indx]);
continue;
}
ac = getacnam((char *)userv[indx]);
if (!ac) {
err1("%s: no such user", (char *)userv[indx]);
continue;
}
strlistadd(&ac->ac_groups, (char *)v[1]);
strlistadd(&gm->gm_mem, (char *)userv[indx]);
sort_list(&ac->ac_groups, pstrcmp);
#ifdef SENDMAIL
for (j=0; j < gm->gm_aliases.l_count; j++) {
al = getalnam((char *)gm->gm_aliases.l_list[j]);
if (!al) continue; /* trouble */
if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) {
strlistadd(&al->al_addresses, (char *)ac->ac_name);
sort_list(&al->al_addresses, pstrcmp);
ModBits |= AL;
}
}
#endif
added++;
}
if (added) {
ModBits |= AC|GR;
sort_list(&gm->gm_mem, pstrcmp);
(void) printf("%d added\n", added);
}
else
err("no change");
non_critical();
return;
}
addtosig(c, v)
int c;
addr *v;
{
struct account *ac;
struct sig *sg;
addr *userv;
int cc, added = 0;
register int indx;
#ifdef SENDMAIL
struct alias *al;
register int j;
#endif
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <sig>", (char *)v[0]);
return;
}
sg = getsgnam((char *)v[1]);
if (!sg) {
err1("%s: no such sig", (char *)v[1]);
return;
}
userv = get_gpa(65);
GetLine("Users: ", 64, &cc, userv, &Users);
if (cc == 0) {
err("no change");
return;
}
critical();
for (indx=0; indx < cc; indx++) {
ac = getacnam((char *)userv[indx]);
if (!ac) {
err1("%s: no such user", (char *)userv[indx]);
continue;
}
if (instrlist(&ac->ac_sigs, (char *)v[1])) {
err1("%s: already is in sig", (char *)userv[indx]);
continue;
}
strlistadd(&ac->ac_sigs, (char *)v[1]);
sort_list(&ac->ac_sigs, pstrcmp);
#ifdef SENDMAIL
for (j=0; j < sg->sg_aliases.l_count; j++) {
al = getalnam((char *)sg->sg_aliases.l_list[j]);
if (!al) continue; /* trouble */
if (!instrlist(&al->al_addresses, (char *)ac->ac_name)) {
strlistadd(&al->al_addresses, (char *)ac->ac_name);
sort_list(&al->al_addresses, pstrcmp);
ModBits |= AL;
}
}
#endif
added++;
}
if (added) {
ModBits |= AC;
(void) printf("%d added\n", added);
}
else
err("no change");
non_critical();
return;
}
adduser(c, v)
int c;
addr *v;
{
struct account *aa;
struct groupmap *gm;
addr *realnamev, *idv, *passwdv, *groupv, *uidv, *shellv;
addr username, def_dir, *dirv;
addr shell, dir;
addr password[SHORT_BUF];
char prompt[MEDIUM_BUF], prompt2[MEDIUM_BUF], *salt;
int cc, uid, n;
addr_t cap[SHORT_BUF];
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c > 1 && userexists((char *)v[1])) {
err1("%s: user exists", (char *) v[1]);
return;
}
if (c > 1) {
(void) strcpy((char *)cap, (char *)v[1]);
capitalize((char *)cap);
rnlist.l_count = 1;
rnlist.l_list[0] = cap;
}
else
rnlist.l_count = 0;
realnamev = get_gpa(17);
do {
GetLine("Real Name: ", 16, &cc, realnamev, &rnlist);
} while (cc == 0 && clear_gpa(realnamev, 17));
/*
* If we were handed a username, take it. If not, we must manufacture
* one from the Real Name.
*/
if (c > 1)
username = v[1];
else {
username = makeusername(cc, realnamev);
(void) printf("login name is \"%s\"\n", username);
}
/*
* Unique identification, like SSN
*/
idv = get_gpa(2);
do {
GetLine("Id: ", 1, &cc, idv, &idlist);
} while (cc == 0 && clear_gpa(idv, 2));
if (!eq(*idv, "exception") && (aa = getacid((char *)*idv))) {
(void) sprintf(prompt, "%s shares that id. continue? [no] ",
(char *)aa->ac_name);
if (no(prompt))
return;
}
/*
* Give the user a password
*/
(void) sprintf(prompt, "Password [%s]: ", *idv);
passwdv = get_gpa(2);
GetLine(prompt, 1, &cc, passwdv, &pwlist);
if (cc)
if (eq(*passwdv, "none"))
(void) strcpy((char *)password, "");
else if (eq(*passwdv, "unused"))
(void) strcpy((char *)password, "*");
else if (eq(*passwdv, "generate")) {
(void) strcpy((char *)password, makepass());
(void) printf("password is \"%s\"\n", password);
}
else {
salt = CRYPT_SALT;
(void) strcpy((char *)password,
crypt((char *)*passwdv, salt));
}
else {
salt = CRYPT_SALT;
(void) strcpy((char *)password, crypt((char *)*idv, salt));
}
(void) sprintf(prompt, "Group [%s]: ", DEF_GROUP);
groupv = get_gpa(2);
do {
GetLine(prompt, 1, &cc, groupv, &Groups);
if (cc) {
gm = getgmnam((char *)*groupv);
if (!gm)
err1("%s: no such group", (char *)*groupv);
else
break;
}
else {
gm = getgmnam(DEF_GROUP);
if (!gm) {
err1("%s: no such group", DEF_GROUP);
continue;
}
break;
}
} while (clear_gpa(groupv, 2));
uid = findnextuid(gm->gm_name);
if (uid == NOMORE) {
err1("no more free uids for group %s!",
gm->gm_name);
return;
}
(void) sprintf(prompt, "Uid [%d]: ", uid);
uidv = get_gpa(2);
do {
GetLine(prompt, 1, &cc, uidv, &Null_List);
if (cc) {
if (!validint((char *)*uidv)) {
err1("%s makes no sense to me", (char *)*uidv);
continue;
}
n = atoi((char *)*uidv);
aa = getacuid(n);
if (aa) {
(void) sprintf(prompt2,
"%s shares that uid, use anyway? ",
aa->ac_name);
if (yesno(prompt2)) {
uid = n;
break;
}
}
else {
uid = n;
break;
}
}
else
break;
} while (clear_gpa(uidv, 2));
/*
* Shell
*/
(void) sprintf(prompt, "Shell [%s]: ", DEF_SHELL);
shellv = get_gpa(2);
GetLine(prompt, 1, &cc, shellv, &Shells);
shell = (cc == 0) ? DEF_SHELL : *shellv;
/*
* Home directory.
*/
def_dir = gethomedir((char *)username, gm->gm_name);
(void) sprintf(prompt, "Home [%s]: ", def_dir);
dirv = get_gpa(2);
GetFilenames(prompt, 1, &cc, dirv);
dir = (cc == 0) ? def_dir : *dirv;
addu(uid, gm->gm_gid, username, glob(realnamev),
(addr)password, *idv, dir, shell);
#ifndef DOFILES
err("Don't forget to create this user's directory!");
#endif
puts("added");
return;
}
addvig(c, v)
int c;
addr *v;
{
if ( c > 2 ) {
err1("%s: too many arguments", (char *)v[0]);
return;
}
if (c != 2) {
err1("usage: %s <name>", (char *)v[0]);
return;
}
if (!groupexists((char *)v[1])) {
err1("%s: no such group", (char *)v[1]);
return;
}
critical();
strlistadd(&Vigs, (char *)v[1]);
sort_list(&Vigs, pstrcmp);
ModBits |= VG;
puts("added");
non_critical();
return;
}
addu(uid, gid, username, realname, password, id, dir, shell)
int uid, gid;
addr username, realname, password, id, dir, shell;
{
struct account ac;
#ifdef SENDMAIL
struct groupmap *gm;
struct alias *al;
register int j;
#endif
#ifdef DOFILES
int zero = 0;
#endif
critical();
#ifdef SENDMAIL
zerolist(&ac.ac_aliases);
#endif
zerolist(&ac.ac_groups);
zerolist(&ac.ac_sigs); zerolist(&ac.ac_classes);
ac.ac_uid = uid;
ac.ac_gid = gid;
savestr((char **)&ac.ac_name, (char *)username);
savestr((char **)&ac.ac_realname, (char *)realname);
savestr((char **)&ac.ac_gecos, (char *)realname);
savestr((char **)&ac.ac_passwd, (char *)password);
savestr((char **)&ac.ac_id, (char *)id);
savestr((char **)&ac.ac_dir, (char *)dir);
savestr((char **)&ac.ac_shell, (char *)shell);
ac.ac_ll.ll_time = (time_t) 0;
(void) strncpy(ac.ac_ll.ll_line, "", sizeof ac.ac_ll.ll_line);
(void) strncpy(ac.ac_ll.ll_host, "", sizeof ac.ac_ll.ll_host);
genlistadd(&AccountList, (addr) &ac, sizeof (struct account));
sort_list(&AccountList, acctcmp);
strlistadd(&Users, (char *)ac.ac_name);
sort_list(&Users, pstrcmp);
#ifdef DOFILES
add_job(JB_MKDIR, ac.ac_dir, (addr)&ac.ac_uid,
(addr)&zero);
#endif
add_job(JB_LASTLOG, (addr) &ac.ac_uid,
(addr)&ac.ac_ll, NIL);
ModBits |= (AC|PW);
#ifdef SENDMAIL
gm = getgmgid(ac.ac_gid);
for (j=0; j < gm->gm_aliases.l_count; j++) {
al = getalnam((char *)gm->gm_aliases.l_list[j]);
if (!al) continue; /* trouble */
if (!instrlist(&al->al_addresses, (char *)ac.ac_name)) {
strlistadd(&al->al_addresses, (char *)ac.ac_name);
sort_list(&al->al_addresses, pstrcmp);
ModBits |= AL;
}
}
#endif
non_critical();
return;
}