#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 #ifdef apollo #include "/sys/ins/base.ins.c" #include "/sys/ins/pad.ins.c" #include "/sys/ins/error.ins.c" #include /* for maximum pathname length */ #include #include #include #include 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 */