Files
Arquivotheca.SunOS-4.1.4/usr.etc/rfs/nlsadmin/main.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

1387 lines
29 KiB
C

/* @(#)main.c 1.1 94/10/31 SMI */
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)nlsadmin:main.c 1.18.2.1"
#include "sys/types.h"
#include "sys/param.h"
#include "tiuser.h"
#include "sys/stat.h"
#include "dirent.h"
#include "stdio.h"
#include "ctype.h"
#include "signal.h"
#include "string.h"
#include "fcntl.h"
#include "nlsadmin.h"
#include "errno.h"
#include "pwd.h"
#include "grp.h"
char *arg0;
int Errno;
char serv_str[16];
char id_str[MAXPATHLEN];
char res_str[MAXPATHLEN];
char flag_str[10];
char mod_str[MAXPATHLEN];
char path_str[MAXPATHLEN];
char cmnt_str[MAXPATHLEN];
char homedir[MAXPATHLEN];
char tempfile[MAXPATHLEN];
#ifdef S4
static char *tempname = "/usr/tmp/.nlstmp";
#else
static char *tempname = "/.nlstmp";
#endif
FILE *tfp;
int nlsuid, nlsgid;
int uid;
char *Netspec;
extern char *erropen;
extern char *errclose;
extern char *errmalloc;
extern char *errchown;
extern char *errscode;
extern char *errperm;
extern char *errdbf;
extern char *errsvc;
extern char *errarg;
extern char *init[];
extern char *malloc();
main(argc, argv)
int argc;
char *argv[];
{
register int flag = 0;
register int c;
register char *net_spec = NULL;
register char *serv_code = NULL;
int qflag = 0;
int nflag = 0;
int errflg = 0;
int adrflg = 0;
int mflag = 0;
char *laddr = NULL;
char *taddr = NULL;
char *id = NULL;
char *res = NULL;
char *pathname = NULL;
char *command = NULL;
char *comment = NULL;
char *modules = NULL;
struct passwd *pwdp;
struct group *grpp;
extern struct passwd *getpwnam();
extern struct group *getgrnam();
extern void exit(), endpwent(), endgrent();
#ifdef S4
char *starname = NULL;
char *pstarname = NULL;
extern char *nlsname();
extern int _nlslog;
#endif
arg0 = argv[0];
Errno = NLSOK;
if (argc == 1)
usage();
uid = getuid();
if (!(grpp = getgrnam(LSGRPNAME))) { /* get group entry */
fprintf(stderr, "%s: no group entry for %s?\n",arg0,LSGRPNAME);
exit(NLSNOGRP);
}
nlsgid = grpp->gr_gid;
endgrent();
/* get password entry for name LSUIDNAME. homedir = LSUIDNAME's home */
if (!(pwdp = getpwnam(LSUIDNAME)) || !(strlen(pwdp->pw_dir))) {
fprintf(stderr,"%s: could not find correct password entry for %s\n",arg0,LSUIDNAME);
exit(NLSNOPASS);
}
nlsuid = pwdp->pw_uid;
strcpy(homedir, HOMEDIR);
endpwent();
umask(022);
/*
* Process arguments.
*/
#ifndef S4
while ((c = getopt(argc, argv, "a:c:d:e:ikl:mnp:qr:st:vw:xy:z:")) != EOF) {
#else
while ((c = getopt(argc, argv, "a:c:d:e:ikl:mnqr:st:vw:xy:z:S:")) != EOF) {
#endif
switch (c) {
case 'a':
flag |= ADD;
if (*optarg != '-')
serv_code = optarg;
break;
case 'c':
flag |= ADD;
if (*optarg != '-')
command = optarg;
break;
case 'd':
flag |= DISBL;
if (*optarg != '-')
serv_code = optarg;
break;
case 'e':
flag |= ENABL;
if (*optarg != '-')
serv_code = optarg;
break;
case 'i':
flag |= INIT;
break;
case 'k':
flag |= KILL;
break;
case 'l':
flag |= ADDR;
adrflg |= LISTEN;
if (*optarg != '-')
laddr = optarg;
else if (strlen(optarg) != 1)
errflg = 1;
break;
case 'm':
mflag = 1;
break;
case 'n':
nflag = 1;
break;
#ifndef S4
case 'p':
flag |= ADD;
if (*optarg != '-')
modules = optarg;
break;
#endif
case 'q':
qflag = 1;
break;
case 'r':
flag |= REM;
if (*optarg != '-')
serv_code = optarg;
break;
case 's':
flag |= START;
break;
case 't':
flag |= ADDR;
adrflg |= TTY;
if (*optarg != '-')
taddr = optarg;
else if (strlen(optarg) != 1)
errflg = 1;
break;
case 'v':
flag |= VERBOSE;
break;
case 'w':
flag |= ADD;
if (*optarg != '-')
id = optarg;
break;
case 'x':
flag |= ALL;
break;
case 'y':
flag |= ADD;
if (*optarg != '-')
comment = optarg;
break;
case 'z':
flag |= ZCODE;
if (*optarg != '-')
serv_code = optarg;
break;
#ifdef S4
case 'S':
flag |= STARLAN;
if (*optarg != '-')
starname = optarg;
break;
#endif
case '?':
errflg = 1;
}
}
if (errflg)
usage();
if (optind < argc)
Netspec = net_spec = argv[optind++];
if (optind < argc)
usage();
/*
* validate service code, if given.
* code follows algorithm in listen:lsdbf.c:get_dbf().
*/
if (serv_code) {
c = strlen(serv_code);
if ((c == 0) || (c >= SVC_CODE_SZ))
error(errsvc, NLSSERV);
if ((c < 5) && isnum(serv_code)) {
c = atoi(serv_code);
if (c == 0)
error(errsvc, NLSSERV);
if (flag == ADD) {
if (mflag) {
if (c > N_DBF_ADMIN)
error(errsvc, NLSSERV);
} else {
if (c < MIN_REG_CODE)
error(errsvc, NLSSERV);
}
}
} else {
if ((flag == ADD) && mflag)
error(errsvc, NLSSERV);
}
}
if (!net_spec) {
if (flag != ALL)
usage();
} else {
if (!ok_netspec(net_spec))
usage();
if ((pathname = (char *)malloc(strlen(homedir)+strlen(net_spec)+strlen(DBFILE)+3)) == NULL)
error(errmalloc, NLSMEM);
sprintf(pathname, "%s/%s/%s", homedir, net_spec, DBFILE);
}
if (net_spec) {
#ifdef S4
(void) strcpy(tempfile, tempname);
#else
(void) strcpy(tempfile, homedir);
(void) strcat(tempfile, "/");
(void) strcat(tempfile, net_spec);
(void) strcat(tempfile, tempname);
#endif
}
if ((flag != ALL) && (flag != INIT) && check_version(pathname))
error("database file is not current version, please convert", NLSVER);
switch (flag) {
case ALL:
if (mflag || qflag || nflag || adrflg || net_spec)
usage();
print_all(homedir);
exit(Errno);
case INIT:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
if (uid != 0)
error(errperm, NLSPERM);
if (access(pathname, 0) < 0) {
/*
if (strchr(net_spec, '\n'))
error(errarg, NLSCMD);
*/
if (!make_db(pathname, net_spec))
error("error in making database file", Errno);
} else {
error("net_spec already initialized",NLSINIT);
}
exit(NLSOK);
case ADD:
if (qflag || nflag || adrflg || !net_spec)
usage();
if (!serv_code || !command || !comment)
usage();
if (uid != 0)
error(errperm, NLSPERM);
/*
if (strchr(serv_code, '\n') || strchr(modules, '\n') ||
strchr(command, '\n') || strchr(comment, '\n') ||
strchr(id, '\n') || strchr(res, '\n'))
error(errarg, NLSCMD);
*/
if (!add_nls(pathname,serv_code,id,res,modules,command,comment,mflag))
error("could not add service", Errno);
break;
case REM:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
if (!serv_code)
usage();
if (uid != 0)
error(errperm, NLSPERM);
if (!rem_nls(pathname, serv_code))
error("could not remove service",Errno);
break;
case ENABL:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
if (!serv_code)
usage();
if (uid != 0)
error(errperm, NLSPERM);
if (!enable_nls(pathname, serv_code))
error("could not enable service",Errno);
break;
case DISBL:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
if (!serv_code)
usage();
if (uid != 0)
error(errperm, NLSPERM);
if (!disable_nls(pathname, serv_code))
error("could not disable service",Errno);
break;
case START:
if (mflag || qflag || adrflg || !net_spec)
usage();
if (uid != 0)
error(errperm, NLSPERM);
start_nls(net_spec, nflag);
/* will exit by itself */
break;
case KILL:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
if (uid != 0)
error(errperm, NLSPERM);
if (!kill_nls(net_spec))
exit(Errno);
exit(NLSOK);
case NONE:
if (mflag || nflag || adrflg || !net_spec)
usage();
if (qflag)
exit(!isactive(net_spec));
else
printf("%s\t%s\n",net_spec,isactive(net_spec)?"ACTIVE":"INACTIVE");
exit(NLSOK);
case VERBOSE:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
print_spec(pathname);
exit(NLSOK);
case ADDR:
if (mflag || qflag || nflag || !net_spec)
usage();
if ((laddr || taddr) && (uid != 0))
error(errperm, NLSPERM);
/*
if (strchr(laddr, '\n') || strchr(taddr, '\n'))
error(errarg, NLSCMD);
*/
if (!chg_addr(net_spec, laddr, taddr, adrflg))
error("error in accessing address file",Errno);
exit(NLSOK);
#ifdef S4
case STARLAN:
if (mflag || qflag || nflag || adrflg || !net_spec)
usage();
if (!starname)
usage();
if (uid != 0)
error(errperm, NLSPERM);
/*
* Nlsname returns null if pstarname will be longer
* than NAMEBUFSZ (currently 64)
*/
_nlslog = 1; /* allows nlsname to use stderr */
if (!(pstarname = nlsname(starname)))
error("error permuting name", NLSADRF);
if (!chg_addr(net_spec, pstarname, starname, LISTEN|TTY))
error("error in accessing address file", Errno);
exit(NLSOK);
#endif
case ZCODE:
if (mflag || nflag || adrflg || !net_spec)
usage();
if (!serv_code)
usage();
print_serv(pathname, serv_code, qflag);
/* will exit by itself */
break;
default:
usage();
}
exit(Errno);
/* NOTREACHED */
}
#ifdef S4
static char *usagemsg = "\
%s: usage: %s -x | %s [ options ] net_spec\n\
\twhere [ options ] are as follows:\n\n\
status: [-q] | [-v] |\n\
start/stop: [-s -n] | [-k] |\n\
initialize: [-i] | \n\
set addresses: [ [-l address|-] [-t address|-] ] |\n\
[-S STARLAN_NETWORK_name] |\n\
query servers: [[-q] -z service_code] |\n\
add server: [ [-m] -a service_code -c \"command\" [-w id] -y \"comment\" ] |\n\
remove server: [-r service_code] |\n\
enable/disable: [-d service_code] | [-e service_code]\n\
";
#else
static char *usagemsg = "\
%s: usage: %s -x or %s [ options ] net_spec\n\
\twhere [ options ] are:\n\
[-q] | [-v] | [-s] | [-k] | [-i] | \n\
[ [-l address|-] [-t address|-] ] |\n\
[ [-m] -a svc_code -c \"cmd\" -y \"comment\" [-p module_list] [-w id]] |\n\
[[-q] -z svc_code] | [-r svc_code] | [-d svc_code] | [-e svc_code]\n\
";
#endif
usage()
{
fprintf(stderr, usagemsg, arg0, arg0, arg0);
exit(NLSCMD);
}
error(s, ec)
char *s;
int ec;
{
fprintf(stderr, "%s: %s\n", arg0, s);
exit(ec);
}
/*
* add an entry to the database, res is reserved for future use, ignore for now
*/
add_nls(fname, serv, id, res, mods, path, comm, flag)
char *fname;
char *serv;
char *id;
char *res;
char *mods;
register char *path;
char *comm;
int flag;
{
register FILE *fp = NULL;
#ifndef S4
struct stat sbuf;
#endif
for (; *path ; path++) /* clean up beginning white space */
if (!isspace(*path))
break;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
if (strlen(serv) > (sizeof(serv_str)-1))
error("service code too long", NLSSERV);
if (find_serv(fp, serv) != -1) {
fprintf(stderr,"%s: service code %s already exists in %s\n",arg0,serv,fname);
Errno = NLSEXIST;
return(0);
}
(void) fclose(fp);
if ((fp = fopen(fname, "a")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
if (!id)
id = DEFAULTID;
if (mods)
fprintf(fp,"%s:%s:%s:reserved:NULL,%s,:%s\t#%s\n",serv,flag?"na":"n",id,mods,path,comm);
else
fprintf(fp,"%s:%s:%s:reserved:NULL,:%s\t#%s\n",serv,flag?"na":"n",id,path,comm);
if (fclose(fp) != 0) {
fprintf(stderr,errclose,arg0,fname,errno);
Errno = NLSCLOSE;
return(0);
}
#ifndef S4
(void) strtok(path, DBFWHITESP);
if (access(path, 0) == 0) {
(void) stat(path, &sbuf);
if (!(sbuf.st_mode & 0111))
fprintf(stderr,"%s: warning - %s not executable\n", arg0, path);
if (!(sbuf.st_mode & S_IFREG))
fprintf(stderr, "%s: warning - %s not a regular file\n", arg0, path);
} else {
fprintf(stderr,"%s: warning - %s not found\n", arg0, path);
}
#endif
return(1);
}
rem_nls(fname, serv_code) /* remove an entry from the database */
char *fname;
char *serv_code;
{
register FILE *fp;
int n;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
if ((n = find_serv(fp, serv_code)) == -1) {
fprintf(stderr,errscode, arg0, serv_code, fname);
Errno = NLSNOCODE;
return(0);
}
if (!open_temp())
return(0);
if (n != 0)
copy_file(fp, 0, n-1);
copy_file(fp, n+1, -1);
if (!close_temp(fname))
return(0);
return(1);
}
enable_nls(fname, serv_code) /* enable a specific service code */
char *fname;
char *serv_code;
{
register FILE *fp;
register char *to, *from;
register char *limit;
char *bp, *copy;
int n;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
if ((n = find_serv(fp, serv_code)) == -1) {
fprintf(stderr,errscode,arg0,serv_code,fname);
Errno = NLSNOCODE;
return(0);
}
if (!open_temp())
return(0);
if (n != 0)
copy_file(fp, 0, n-1);
else
fseek(fp, 0L, 0);
if ((bp = (char *)malloc(DBFLINESZ)) == NULL)
error(errmalloc, NLSMEM);
if ((copy = (char *)malloc(DBFLINESZ)) == NULL)
error(errmalloc, NLSMEM);
if (!fgets(bp,DBFLINESZ,fp)) {
(void) unlink(tempfile);
error(errdbf, NLSRDFIL);
}
limit = strchr(bp, (int)':');
for (to = copy, from = bp; from < limit; )
*to++ = *from++;
*to++ = *from++; /* copy ":" */
limit = strchr(from, (int)':');
for ( ; from < limit ; ) {
if (*from == 'x' || *from == 'X') {
from++;
continue;
}
*to++ = *from++;
}
for ( ; *from ; )
*to++ = *from++;
*to = '\0';
fprintf(tfp, "%s", copy);
free(bp);
free(copy);
copy_file(fp, n+1, -1);
(void) fclose(fp);
if (!close_temp(fname))
return(0);
return(1);
}
disable_nls(fname, serv_code) /* disable a specific service code */
char *fname;
char *serv_code;
{
register FILE *fp;
register char *to, *from;
register char *limit;
char *bp, *copy;
int n;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
if ((n = find_serv(fp, serv_code)) == -1) {
fprintf(stderr,errscode,arg0,serv_code,fname);
Errno = NLSNOCODE;
return(0);
}
if (!open_temp())
return(0);
if (n != 0)
copy_file(fp, 0, n-1);
else
fseek(fp, 0L, 0);
if ((bp = (char *)malloc(DBFLINESZ)) == NULL)
error(errmalloc, NLSMEM);
if ((copy = (char *)malloc(DBFLINESZ)) == NULL)
error(errmalloc, NLSMEM);
if (!fgets(bp,DBFLINESZ,fp)) {
(void) unlink(tempfile);
error(errdbf, NLSRDFIL);
}
limit = strchr(bp, (int)':');
for (to = copy, from = bp; from < limit; )
*to++ = *from++;
*to++ = *from++; /* copy ":" */
limit = strchr(from, (int)':');
for ( ; from < limit ; ) {
if (*from == 'x' || *from == 'X') {
from++;
continue;
}
*to++ = *from++;
}
*to++ = 'x';
for ( ; *from ; )
*to++ = *from++;
*to = '\0';
fprintf(tfp, "%s", copy);
free(bp);
free(copy);
copy_file(fp, n+1, -1);
(void) fclose(fp);
if (!close_temp(fname))
return(0);
return(1);
}
isdir(s) /* check to see if a directory exists */
char *s;
{
struct stat sbuf;
if (stat(s, &sbuf) != 0) {
fprintf(stderr, "%s: could not stat %s, errno = %d\n",arg0,s,errno);
Errno = NLSSTAT;
return(0);
}
if ((sbuf.st_mode & FILETYPE) == DIRECTORY)
return(1);
else
return(0);
}
isnum(s) /* check to see if s is a numeric string */
register char *s;
{
if (!*s)
return(0);
while(*s)
if (!isdigit(*s++))
return(0);
return(1);
}
isactive(name) /* is a listener active? */
char *name;
{
char lockname[MAXPATH];
int fd;
struct stat sbuf;
sprintf(lockname, "%s/%s", homedir, name);
if (access(lockname, 0) < 0) {
fprintf(stderr, erropen, arg0, name);
exit(NLSNOTF);
}
strcat(lockname, "/");
strcat(lockname, LOCKFILE);
/* check to see if modes are okay */
if (stat(lockname, &sbuf) != 0) {
/* Errno = NLSSTAT */
return(0);
}
if ((sbuf.st_mode & ALLPERM) != LOCKPERM) {
if (uid == 0 || uid == nlsuid)
chmod(lockname, LOCKPERM);
else {
fprintf(stderr,"%s: bad modes for file %s - retry as super user\n",arg0,lockname);
exit(NLSPERM);
}
}
/* open file with open(2) */
if ((fd = open(lockname, O_RDWR)) < 0) {
/* Errno = NLSOPEN */
return(0);
}
if (LOCK(fd, 2, 0L) == -1) {
close(fd);
return(1);
}
close(fd);
return(0);
}
make_db(fname, nspec) /* create the database file */
char *fname;
char *nspec;
{
register FILE *fp = NULL;
register FILE *afp = NULL;
register int i;
register char *ptr, *savptr;
char addrname[MAXPATH];
char newname[MAXPATH];
char parent[MAXPATH];
/* assume homedir already exists */
/* make directory(s) for net_spec */
umask(0);
sprintf(addrname, "%s/%s", homedir, nspec);
strcpy(parent, homedir);
ptr = addrname+strlen(homedir)+1;
do {
savptr = ptr;
ptr = strchr(ptr, (int)'/');
if (ptr == savptr || !ptr)
i = strlen(addrname);
else
i = ptr - addrname;
strncpy(newname, addrname, i);
newname[i] = (char)0;
if ((access(newname,0) < 0) && (errno == ENOENT)){
if (mkdir(newname, 0777) < 0) {
fprintf(stderr, "%s: could not create %s\n",
arg0, newname);
perror("mkdir");
Errno = NLSCREAT;
return(0);
}
}
strcpy(parent, newname);
} while ((ptr != savptr) && (ptr++ != (char *)NULL));
umask(022);
/* create files */
strcat(addrname, "/");
strcat(addrname, ADDRFILE);
if ((fp = fopen(fname, "w")) == NULL) {
fprintf(stderr,"%s: could not create %s, errno = %d\n",arg0,fname,errno);
Errno = NLSCREAT;
return(0);
}
if ((afp = fopen(addrname, "w")) == NULL) {
fprintf(stderr,"%s: could not create %s, errno = %d\n",arg0,addrname,errno);
Errno = NLSCREAT;
return(0);
}
init_db(fp);
if (fclose(fp) != 0) {
fprintf(stderr,errclose,arg0,fname,errno);
Errno = NLSCLOSE;
return(0);
}
if (chown(fname, nlsuid, nlsgid) < 0) {
fprintf(stderr,errchown,arg0, fname, errno);
Errno = NLSCHOWN;
return(0);
}
fprintf(afp,"\n\n");
if (fclose(afp) != 0) {
fprintf(stderr,errclose,arg0,addrname,errno);
Errno = NLSCLOSE;
return(0);
}
if (chown(addrname, nlsuid, nlsgid) < 0) {
fprintf(stderr,errchown,arg0, addrname, errno);
Errno = NLSCHOWN;
return(0);
}
umask(0);
sprintf(addrname, "%s/%s/%s", homedir, nspec, LOCKFILE);
if ((fp = fopen(addrname, "w")) == NULL) {
fprintf(stderr,"%s: could not create %s, errno = %d\n",arg0,addrname,errno);
Errno = NLSCREAT;
return(0);
}
if (fclose(fp) != 0) {
fprintf(stderr,errclose,arg0,addrname,errno);
Errno = NLSCLOSE;
return(0);
}
if (chown(addrname, nlsuid, nlsgid) < 0) {
fprintf(stderr,errchown,arg0, addrname, errno);
Errno = NLSCHOWN;
return(0);
}
umask(022);
return(1);
}
chg_addr(fname, la, ta, flag)
char *fname;
char *la;
char *ta;
register int flag;
{
register FILE *fp = NULL;
char addrname[MAXPATH];
char adr1[NAMEBUFSZ];
char adr2[NAMEBUFSZ];
char *p;
adr1[0] = (char)0;
adr2[0] = (char)0;
sprintf(addrname, "%s/%s/%s", homedir, fname, ADDRFILE);
if ((fp = fopen(addrname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
(void) fgets(adr1, NAMEBUFSZ, fp);
(void) fgets(adr2, NAMEBUFSZ, fp);
if (ferror(fp)) {
fprintf(stderr,"%s: error in reading address file\n",arg0);
(void) fclose(fp);
Errno = NLSADRF;
return(0);
}
(void) fclose(fp);
if (adr1[0] == (char)0)
adr1[0] = '\n';
if (adr2[0] == (char)0)
adr2[0] = '\n';
if(p = strrchr(adr1, (int)'\n'))
*p = (char)0;
if(p = strrchr(adr2, (int)'\n'))
*p = (char)0;
fp = NULL;
/*
* check to make sure the addresses are different before we zap the addr file
* 3 cases exist, we are changing both, just la, or just ta
*/
if ((la && ta && !strcmp(la, ta)) || (la && !ta && !strcmp(la, adr2)) || (!la && ta && !strcmp(adr1, ta))) {
fprintf(stderr, "%s: listening addresses not unique\n", arg0);
Errno = NLSNOTUNIQ;
/*
* this little piece allows stuff like "nlsadmin -l addr -t- netspec"
* to still print out the 'other' address even if the update fails. Note
* that fp will be NULL after this.
*/
if (la) {
flag &= ~LISTEN;
la = NULL;
}
if (ta) {
flag &= ~TTY;
ta = NULL;
}
}
if (!la) {
if (flag & LISTEN)
printf("%s\n",adr1);
} else {
if ((fp = fopen(addrname, "w")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
fprintf(fp, "%s\n", la);
}
if (!ta) {
if (flag & TTY) {
if (adr2[0] != (char)0)
printf("%s\n",adr2);
else
fprintf(stderr, "Terminal login service address not configured\n");
}
if (fp)
fprintf(fp, "%s\n", adr2);
} else {
if (!fp) {
if ((fp = fopen(addrname, "w")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return(0);
}
fprintf(fp, "%s\n", adr1);
}
fprintf(fp, "%s\n", ta);
}
if (fp) {
if (fclose(fp) != 0) {
fprintf(stderr,errclose,arg0,addrname,errno);
Errno = NLSCLOSE;
return(0);
}
if (chown(addrname, nlsuid, nlsgid) < 0) {
fprintf(stderr,errchown,arg0, addrname, errno);
Errno = NLSCHOWN;
return(0);
}
}
if (Errno == NLSNOTUNIQ)
return(0);
else
return(1);
}
init_db(fp) /* initialize the database file */
FILE *fp;
{
register int i;
for ( i=0; init[i]; i++)
fprintf(fp,"%s\n",init[i]);
}
copy_file(fp, start, finish)
register FILE *fp;
register int start;
register int finish;
{
register int i;
char dummy[DBFLINESZ];
fseek(fp,0L,0);
if (start != 0) {
for (i = 0; i < start; i++)
if (!fgets(dummy,DBFLINESZ,fp)) {
(void) unlink(tempfile);
error(errdbf, NLSRDFIL);
}
}
if (finish != -1) {
for (i = start; i <= finish; i++) {
if (!fgets(dummy, DBFLINESZ, fp)) {
(void) unlink(tempfile);
error(errdbf, NLSRDFIL);
}
if (fputs(dummy,tfp) == EOF) {
(void) unlink(tempfile);
error("error in writing tempfile", NLSDBF);
}
} /* for */
} else {
for ( ; ; ) {
if (fgets(dummy, DBFLINESZ, fp) == NULL) {
if (feof(fp)) {
break;
} else {
(void) unlink(tempfile);
error(errdbf, NLSRDFIL);
}
}
if (fputs(dummy,tfp) == EOF) {
(void) unlink(tempfile);
error("error in writing tempfile", NLSDBF);
}
} /* for */
} /* if */
}
find_pid(name)
char *name;
{
char pidname[MAXPATH];
char pidchar[10];
FILE *fp;
sprintf(pidname, "%s/%s/%s", homedir, name, PIDFILE);
if ((fp = fopen(pidname, "r")) == NULL)
return(0);
if (fscanf(fp, "%s", pidchar) != 1) {
(void) fclose(fp);
return(0);
}
(void) fclose(fp);
return((int)strtol(pidchar, (char **)NULL, 10));
}
start_nls(name, flag)
char *name;
int flag;
{
register char *lstr, *tstr;
char addrname[MAXPATH];
char buff[100];
FILE *fp;
struct netbuf *lbuf = NULL;
struct netbuf *tbuf = NULL;
int taddr = 0; /* true if remote tty address specified */
extern struct netbuf *stoa();
extern void nlsaddr2c();
if (isactive(name))
error("listener already active",NLSACTIV);
if (flag)
sprintf(buff, "%s/%s/%s", homedir, name, LISTENER);
else
sprintf(buff, "%s/%s", homedir, LISTENER);
/* read addr file */
sprintf(addrname, "%s/%s/%s", homedir, name, ADDRFILE);
if ((fp = fopen(addrname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
exit(NLSOPEN);
}
if ((lstr = (char *)malloc(NAMEBUFSZ))==NULL)
error(errmalloc, NLSMEM);
if ((tstr = (char *)malloc(NAMEBUFSZ))==NULL)
error(errmalloc, NLSMEM);
*lstr = (char)0;
*tstr = (char)0;
(void) fgets(lstr, NAMEBUFSZ, fp);
(void) fgets(tstr, NAMEBUFSZ, fp);
if (*lstr == '\n') {
fprintf(stderr,"%s: address not initialized for %s\n",arg0,name);
(void) fclose(fp);
exit(NLSADRF);
}
if (*lstr == (char)0 || *tstr == (char)0) {
fprintf(stderr,"%s: error in reading, or bad address file\n",arg0);
(void) fclose(fp);
exit(NLSADRF);
}
*(lstr + strlen(lstr) -1) = (char)0;
*(tstr + strlen(tstr) -1) = (char)0;
if (*tstr)
taddr = 1;
/* call stoa - convert from rfs address to netbuf */
if ((lbuf = stoa(lstr, lbuf)) == NULL)
error(errmalloc, NLSMEM);
if (taddr) {
if ((tbuf = stoa(tstr, tbuf)) == NULL)
error(errmalloc, NLSMEM);
}
/* call nlsaddr2c - convert from netbuf to listener format */
free(lstr);
free(tstr);
if ((lstr = (char *)malloc(NAMEBUFSZ*2+1))==NULL)
error(errmalloc, NLSMEM);
if (taddr) {
if ((tstr = (char *)malloc(NAMEBUFSZ*2+1))==NULL)
error(errmalloc, NLSMEM);
}
nlsaddr2c(lstr, lbuf->buf, lbuf->len);
if (taddr)
nlsaddr2c(tstr, tbuf->buf, tbuf->len);
(void) fclose(fp);
if (taddr)
execl( buff, LISTENER, "-n", name, "-l", lstr, "-r", tstr, 0);
else
execl( buff, LISTENER, "-n", name, "-l", lstr, 0);
error("could not exec listener", NLSEXEC );
}
kill_nls(name)
char *name;
{
int pid;
if (!isactive(name)) {
fprintf(stderr,"%s: there is no listener active for %s\n",arg0,name);
Errno = NLSDEAD;
return(0);
}
if((pid = find_pid(name)) == 0) {
fprintf(stderr, "%s: could not find pid to send SIGTERM\n",arg0);
Errno = NLSFINDP;
return(0);
}
if (kill(pid, SIGTERM) != 0) {
fprintf(stderr, "%s: could not send SIGTERM to listener, errno = %d\n",arg0,errno);
Errno = NLSSIG;
return(0);
}
return(1);
}
close_temp(fname)
char *fname;
{
if (fclose(tfp) == EOF) {
fprintf(stderr,errclose,arg0,errno);
Errno = NLSCLOSE;
(void) unlink(tempfile);
return(0);
}
if (unlink(fname)) {
fprintf(stderr,"%s: cannot unlink %s, errno = %d\n", arg0, fname,errno);
Errno = NLSULINK;
(void) unlink(tempfile);
return(0);
}
if (link(tempfile, fname)) {
fprintf(stderr,"%s: cannot link %s to %s, errno = %d\n", arg0, tempfile, fname,errno);
Errno = NLSLINK;
(void) unlink(tempfile);
return(0);
}
if (unlink(tempfile)) {
fprintf(stderr,"%s: cannot unlink %s, errno = %d\n",arg0,tempfile,errno);
Errno = NLSULINK;
return(0);
}
if (chown(fname, nlsuid, nlsgid) < 0) {
fprintf(stderr,errchown,arg0, fname, errno);
Errno = NLSCHOWN;
return(0);
}
return(1);
}
open_temp()
{
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
umask(0333);
if (access(tempfile,0) >= 0) {
fprintf(stderr, "%s: tempfile busy; try again later\n", arg0);
Errno = NLSBUSY;
return(0);
}
if ((tfp = fopen(tempfile, "w")) == NULL) {
fprintf(stderr, "%s: cannot create tempfile, errno = %d\n", arg0,errno);
Errno = NLSCREAT;
return(0);
}
umask(022);
return(1);
}
find_serv(fp, code) /* find a service routine */
FILE *fp;
char *code;
{
register int n;
register int total = -1;
extern int read_dbf();
/*
* read_dbf() returns a line number relative to the file pointer.
* total is the absolute file offset.
*/
while ((n = read_dbf(fp)) >= 0) {
if (total == -1)
total = n;
else
total = total + n + 1;
if (strncmp(serv_str, code, SVC_CODE_SZ) == 0)
return(total);
}
if (n == -2)
error("error in reading database file", Errno);
return(-1);
}
print_spec(fname)
char *fname;
{
FILE *fp;
register int n;
int ignore;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
Errno = NLSOPEN;
return;
}
while ((n = read_dbf(fp)) >= 0) {
ignore = (int)strchr(flag_str, (int)'x') +
(int)strchr(flag_str, (int)'X');
#ifdef S4
printf("%s\t%s\t%s\t%s\t%s\n",serv_str, ignore?"DISABLED":"ENABLED ",id_str,path_str,cmnt_str);
#else
if (mod_str[0] == (char)0)
printf("%s\t%s\t%s\tNOMODULES\t%s\t%s\n",serv_str, ignore?"DISABLED":"ENABLED ",id_str,path_str,cmnt_str);
else
printf("%s\t%s\t%s\t%s\t%s\t%s\n",serv_str, ignore?"DISABLED":"ENABLED ",id_str,mod_str,path_str,cmnt_str);
#endif /* S4 */
}
if (n == -2)
error("error in reading database file", Errno);
(void) fclose(fp);
}
print_all(dir) /* CAUTION: recursive routine */
char *dir;
{
register char dirname[MAXNAMLEN];
char *nspec;
struct dirent *dp;
DIR *dfp;
if ((dfp = opendir(dir)) == (DIR *) NULL)
error(errdbf, NLSRDFIL);
while ((dp = readdir(dfp)) != (struct dirent *) NULL) {
sprintf(dirname,"%s/%s",dir,dp->d_name);
if (!strcmp(dp->d_name, ".") || ! strcmp(dp->d_name, ".."))
continue;
if (isdir(dirname)) {
print_all(dirname);
} else {
if (strcmp(dp->d_name, DBFILE) == 0) {
nspec = dir + strlen(homedir) + 1;
printf("%s\t%s\n",nspec,isactive(nspec)?"ACTIVE":"INACTIVE");
}
}
}
closedir(dfp);
}
print_serv(fname, code, flag)
char *fname;
char *code;
int flag;
{
register FILE *fp;
register int ignore;
if ((fp = fopen(fname, "r")) == NULL) {
fprintf(stderr, erropen, arg0, Netspec);
exit(NLSOPEN);
}
if (find_serv(fp, code) == -1) {
fprintf(stderr,errscode, arg0, code, fname);
exit(NLSNOCODE);
}
(void) fclose(fp);
ignore = (int)strchr(flag_str, (int)'x') + (int)strchr(flag_str, (int)'X');
if (ignore)
ignore = 1;
if (flag)
exit(ignore);
#ifdef S4
printf("%s\t%s\t%s\t%s\t%s\n",serv_str, ignore?"DISABLED":"ENABLED ",id_str,path_str,cmnt_str);
#else
if (mod_str[0] == (char)0)
printf("%s\t%s\t%s\tNOMODULES\t%s\t%s\n",serv_str, ignore?"DISABLED":"ENABLED ",id_str,path_str,cmnt_str);
else
printf("%s\t%s\t%s\t%s\t%s\t%s\n",serv_str, ignore?"DISABLED":"ENABLED ",id_str,mod_str,path_str,cmnt_str);
#endif /* S4 */
exit(NLSOK);
}
ok_netspec(nspec) /* validates a net_spec name */
char *nspec;
{
register int size;
register char *cp, *n;
if (!nspec)
return(0);
if (*nspec == '/')
return(0);
for (cp = nspec; *cp; cp += size) {
if (*cp == '.')
return(0);
if ((n = strchr(cp, (int)'/')) == NULL)
size = strlen(cp);
else
size = n - cp + 1;
}
return(1);
}