243 lines
4.7 KiB
C
Executable File
243 lines
4.7 KiB
C
Executable File
#ident "@(#)apollo.c 1.3 93/06/08 SMI" /* From AT&T Toolchest */
|
|
|
|
/*
|
|
* UNIX ksh
|
|
*
|
|
* D. G. Korn
|
|
* Bell Telephone Laboratories
|
|
* adapted from APOLLO changes to Bourne Shell
|
|
*
|
|
*/
|
|
|
|
#include "defs.h"
|
|
#include <errno.h>
|
|
|
|
#ifdef apollo
|
|
#include "/sys/ins/base.ins.c"
|
|
#include "/sys/ins/pad.ins.c"
|
|
#include "/sys/ins/error.ins.c"
|
|
#include <sys/param.h> /* for maximum pathname length */
|
|
#include <apollo/sys/ubase.h>
|
|
#include <apollo/sys/name.h>
|
|
#include <apollo/error.h>
|
|
#include <string.h>
|
|
|
|
int
|
|
pad_create(fname)
|
|
char *fname;
|
|
{
|
|
short oldfd = 1;
|
|
short newfd;
|
|
short size = 25;
|
|
long st;
|
|
|
|
pad_$create (*fname, (short)strlen(fname), pad_$edit, oldfd,
|
|
pad_$bottom, 0, size, newfd, st);
|
|
if (st != 0)
|
|
sh_fail("dm pad",e_open);
|
|
return(newfd);
|
|
}
|
|
|
|
pad_wait(fd)
|
|
int fd;
|
|
{
|
|
long st;
|
|
|
|
pad_$edit_wait((stream_$id_t)fd, st);
|
|
|
|
return (st == 0 ? 0 : 1);
|
|
|
|
}
|
|
|
|
char *
|
|
apollo_error()
|
|
{
|
|
extern long unix_proc_$status;
|
|
char subsys[80], module[80], code[80];
|
|
short slen, mlen, clen;
|
|
static char retstr[256];
|
|
|
|
error_$get_text (unix_proc_$status, subsys, slen,
|
|
module, mlen, code, clen);
|
|
subsys[slen] = module[mlen] = code[clen] = 0;
|
|
if (clen == 0)
|
|
sprintf (code, "status 0x%08x", unix_proc_$status);
|
|
if ( mlen )
|
|
sprintf(retstr, "%s (%s/%s)", code, subsys, module );
|
|
else
|
|
sprintf(retstr, "%s (%s)", code, subsys );
|
|
|
|
return (retstr);
|
|
}
|
|
|
|
/*
|
|
* declarations to support the apollo builtin commands
|
|
* rootnode, inlib, and ver.
|
|
*/
|
|
|
|
static char last_rootnode[MAXPATHLEN] = "/";
|
|
static char do_ver;
|
|
static char *preval = NULL, *sysval, *sysid = "SYSTYPE";
|
|
|
|
/*
|
|
* code to support the apollo builtin functions rootnode,
|
|
* inlib, and ver.
|
|
*/
|
|
|
|
int b_rootnode(argn,com)
|
|
char **com;
|
|
{
|
|
if (argn == 1)
|
|
{ /* report current setting */
|
|
p_setout(st.standout);
|
|
p_str(last_rootnode, NL);
|
|
return(0);
|
|
}
|
|
if (!is_valid_rootnode(com[1]))
|
|
sh_cfail(e_rootnode);
|
|
if (rootnode(com[1]) != 0)
|
|
{
|
|
perror("rootnode: "); /* ? */
|
|
sh_cfail(e_rootnode);
|
|
}
|
|
if (argn == 2)
|
|
strcpy(last_rootnode, com[1]);
|
|
else
|
|
{
|
|
sysval = com[1];
|
|
com = &com[2];
|
|
sh.un.com = &com[1]; /* set up arg list for sh_eval */
|
|
sh_eval(com[0]);
|
|
if (rootnode(last_rootnode) != 0)
|
|
sh_cfail(e_rootnode);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
int b_ver(argn,com)
|
|
char **com;
|
|
{
|
|
char *oldver;
|
|
short i1, i2;
|
|
std_$call unsigned char c_$decode_version();
|
|
|
|
oldver = SYSTYPENOD->value.namval.cp;
|
|
if (argn == 1 || argn > 2)
|
|
{
|
|
sysval = NULL;
|
|
if (oldver)
|
|
preval = sysval = oldver;
|
|
}
|
|
if (argn == 1)
|
|
{
|
|
if (!oldver || !sysval)
|
|
sh_cfail(e_nover);
|
|
else
|
|
{
|
|
p_setout(st.standout);
|
|
p_str(sysval, NL) ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!c_$decode_version (*com[1], (short) strlen (com[1]), i1, i2))
|
|
sh_cfail(e_badver);
|
|
else
|
|
{
|
|
if (argn == 2)
|
|
{
|
|
short namlen = strlen(sysid);
|
|
short arglen = strlen(com[1]);
|
|
|
|
nam_free(SYSTYPENOD);
|
|
nam_fputval(SYSTYPENOD, com[1]);
|
|
nam_ontype(SYSTYPENOD, N_EXPORT | N_FREE);
|
|
ev_$set_var (sysid, &namlen, com[1], &arglen);
|
|
}
|
|
else
|
|
{
|
|
int fd;
|
|
short namlen = strlen(sysid);
|
|
short arglen = strlen(com[1]);
|
|
|
|
sysval = com[1];
|
|
com = &com[2];
|
|
sh.un.com = &com[1]; /* set up arg list for sh_eval */
|
|
ev_$set_var(sysid, &namlen, sysval, &arglen);
|
|
if((fd=path_open(com[0],path_get(com[0]))) < 0)
|
|
{
|
|
arglen = (short)strlen(preval);
|
|
ev_$set_var (sysid, &namlen, preval, &arglen);
|
|
sh_fail(com[0],e_found);
|
|
}
|
|
close(fd);
|
|
sh_eval(com[0]);
|
|
arglen = (short)strlen(preval);
|
|
ev_$set_var (sysid, &namlen, preval, &arglen);
|
|
}
|
|
}
|
|
}
|
|
return(sh.exitval);
|
|
}
|
|
|
|
/*
|
|
* rootnode.c - a chroot call which doesn't require you to be root...
|
|
*/
|
|
|
|
/*
|
|
* Changes:
|
|
01/24/88 brian Initial coding
|
|
*/
|
|
|
|
|
|
#ifndef NULL
|
|
# define NULL ((void *) 0)
|
|
#endif
|
|
|
|
extern boolean
|
|
unix_fio_$status_to_errno(
|
|
status_$t & status,
|
|
char * pn,
|
|
short & pnlen
|
|
);
|
|
|
|
is_valid_rootnode(path)
|
|
char *path;
|
|
{
|
|
if (geteuid() == 0)
|
|
return 1;
|
|
return (path[0] == '/' && path[1] == '/' && path[2] != '\0' &&
|
|
strchr(&path[2], '/') == NULL);
|
|
}
|
|
|
|
rootnode(path)
|
|
char *path;
|
|
{
|
|
uid_$t dir_uid, rtn_uid;
|
|
name_$pname_t new_root_name, rest_path;
|
|
name_$name_t leaf;
|
|
short rest_len, leaf_len, err;
|
|
status_$t status;
|
|
|
|
strcpy(new_root_name, path);
|
|
|
|
name_$resolve_afayc(new_root_name, (short)strlen(new_root_name),
|
|
&dir_uid, &rtn_uid, rest_path, &rest_len, leaf, &leaf_len, &err, &status);
|
|
|
|
if (status.all != status_$ok) {
|
|
unix_fio_$status_to_errno(status, path, strlen(path));
|
|
return (-1);
|
|
}
|
|
|
|
name_$set_diru(rtn_uid, rest_path, (short) rest_len, name_$node_dir_type, &status);
|
|
|
|
if (status.all != status_$ok) {
|
|
unix_fio_$status_to_errno(status, path, strlen(path));
|
|
return(-1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
#endif /* apollo */
|
|
|