6ef3d4560951e6422cb64ef890bd2e97a924d9c0
static char sccsid
[] = " unixtraps.c 1.1 82/05/12 ";
/* Function to execute version 6 and version 7 UNIX system calls from
* compatability mode on UNIX-32V.
#define RTSNAME "/../../../../usr/local/v6trc"
#define RTSNAME "/../../../../usr/local/v6run"
#define RTSNAME "/../../../../usr/local/v7trc"
#define RTSNAME "/../../../../usr/local/v7run"
char argvs
[ARGVLEN
+ENVLEN
];
/* 32v type stat structure */
extern struct stat stat32v
;
/* place for times data so we can reverse the longs */
/* place for pipe file descriptors */
/* version 6 style stat structure */
/* do the trap stuff for the trap with code */
register unsigned short *argp
, *savp
, *savep
;
register int i
, j
, indirflg
;
register char *avp
, *oavp
;
/* clear out condition codes of psl */
/* special case of indirect sys call */
/* remember this was indirect */
argp
= (unsigned short *)*(pc
++);
/* code for indirect sys call */
fprintf(stderr
,"Bad indirect sys call at 0x%x\n",pc
-2);
/* remember this was not indirect */
/* check if code too high or bad sys code */
if(code
>= NSYSTRAPS
|| sysargs
[code
][0] == ILLSYS
) {
fprintf(stderr
,"Unimplimented trap %d at 0x%x\n",code
,argp
);
/* copy args to known locations */
for(j
=0; j
<sysargs
[code
][0]; j
++) args
[i
++] = regs
[j
];
for(j
=0; j
<(sysargs
[code
][1]); j
++) args
[i
++] = *argp
++;
fprintf(stderr
,"pid %d ",getpid());
if(indirflg
) fprintf(stderr
,"indirect ");
fprintf(stderr
,"%s (%d) from 0%o with %d args",sysnames
[code
],code
,pc
-1,i
);
fprintf(stderr
," 0%o",args
[j
]);
if(code
==OPEN
||code
==STAT
||code
==CREAT
||code
==EXEC
||code
==UNLNK
||code
==LINK
||code
==CHDIR
||code
==MKNOD
)
fprintf(stderr
," (%s)",args
[0]);
fprintf(stderr
," (%s)",args
[0]);
fprintf(stderr
," (%s)",args
[1]);
/* go do whatever sys call it is */
/* indirect forks return pids on both sides - must do here */
/* this is possibly a bug in 32V */
* have to do a lot of junk here to fix up an argv
* for execute since (1) the pdp-11 argv consists of 16
* bit pointers and (2) the argv itself is in the
* pdp-11 program space where it would get clobbered
* when a new program is read in and before its
savp
= (unsigned short *)args
[1];
for(i
=1; args
[i
] = *savp
++; i
++)
if(args
[i
] == 0177777) break;
else fprintf(stderr
,"argv[%d]%s ",i
-1,args
[i
]);
savep
= (unsigned short *)args
[2];
for(i
=1; args
[i
] = *savp
++; i
++)
fprintf(stderr
,"argv[%d]%s ",i
-1,args
[i
]);
if(stat(args
[0], &stat32v
)) {
/* return error here if file does not exist */
fprintf(stderr
," does not exist\n");
/* must have execute permission */
if(stat32v
.st_mode
& (S_IEXEC
>>6)) goto experm
;
if(stat32v
.st_mode
& (S_IEXEC
>>3)) {
if(stat32v
.st_gid
== getegid()) goto experm
;
if(geteuid() == 0) goto experm
;
if(stat32v
.st_mode
& S_IEXEC
) {
if(stat32v
.st_uid
== geteuid()) goto experm
;
if(geteuid() == 0) goto experm
;
/* return failure if no exec permision allowed */
/* can't exec a directory */
if(stat32v
.st_mode
& S_IFDIR
)
while(*avp
++ = *oavp
++) ;
for(j
= ++i
; args
[j
] = *savep
++; j
++) ;
while(*avp
++ = *oavp
++) ;
/* SETUID and SETGID files must be started with a fresh RTS */
if(stat32v
.st_mode
& S_ISGID
|| stat32v
.st_mode
& S_ISUID
) {
/* should add a check here for good magic # in header */
fprintf(stderr
," SETUID-GID");
i
= execve(args
[0], &args
[0], &args
[i
]);
i
= execv(args
[0], &args
[0]);
fprintf(stderr
,"can't exec %s\n",RTSNAME
);
i
= execute(args
[0], &args
[1], &args
[i
]);
/* shouldn't get here if exec works */
/* fix up negative offsets */
if(args
[2] != 0 && args
[2] != 3)
if(args
[1] >= 32768) args
[1] -= 65536;
i
= lseek(args
[0], args
[1], args
[2]);
i
= lseek(args
[0], args
[1]*512, args
[2]-3);
i
= lseek(args
[0], (args
[1]<<16)|(args
[2]&0177777), args
[3]);
/* version 6 uses allocated bit which means regular file here */
i
= mknod(args
[0], args
[1], args
[2]);
i
= lseek(args
[0], 0L, 1);
/* do the syscall to a local stat buffer */
i
= syscall(code
, args
[0], &stat32v
);
stat32v
.st_size
= longrev(stat32v
.st_size
);
stat32v
.st_atime
= longrev(stat32v
.st_atime
);
stat32v
.st_mtime
= longrev(stat32v
.st_mtime
);
stat32v
.st_ctime
= longrev(stat32v
.st_ctime
);
/* copy out otherwise unchanged stat buffer */
/* in two pieces with st_size as the breaking point */
/* note that st_rdev is a short but due to alingnmemt */
/* problems the rest of the structure is out of sync */
j
= (int)((char *)(&stat32v
.st_size
)-(char *)(&stat32v
.st_dev
));
bcopy(&stat32v
, args
[1], j
);
bcopy(&stat32v
.st_size
, args
[1]+j
-2, sizeof(struct stat
)-j
);
/* point to user area as v6stat structure */
v6stat
= (struct v6nod
*)args
[1];
/* copy out piece by piece */
v6stat
->majmin
= stat32v
.st_dev
;
v6stat
->inumber
= stat32v
.st_ino
;
v6stat
->flags
= stat32v
.st_mode
;
v6stat
->nlinks
= (unsigned char)stat32v
.st_nlink
;
v6stat
->uid
= (unsigned char)stat32v
.st_uid
;
v6stat
->gid
= (unsigned char)stat32v
.st_gid
;
/* note size already reversed */
v6stat
->size0
= (unsigned char)(stat32v
.st_size
& 0377);
v6stat
->size1
= (unsigned short)(stat32v
.st_size
>>16);
v6stat
->actime
= stat32v
.st_atime
;
v6stat
->modtime
= stat32v
.st_mtime
;
/* for now just set 100000 bit if not a plain file */
if(v6stat
->flags
& 060000)
v6stat
->flags
|= 0100000;
timebuf
.t2
= longrev(timebuf
.t2
) + timebuf
.t1
;
timebuf
.t3
= longrev(timebuf
.t3
);
timebuf
.t4
= longrev(timebuf
.t4
);
bcopy(&timebuf
.t2
,args
[0],sizeof(struct timebuf
)-sizeof(long));
/* do a sleep function - what about pwb which has alarm? */
i
= args
[1]<<8 | args
[0];
i
= args
[1]<<8 | args
[0];
/* uids and gids are 8 bits in version 6 */
i
= syscall(code
,args
[0]&0377);
/* if it is a good signal code */
/* get the current signal value */
/* reset the signal to the new value */
sigvals
[args
[0]] = args
[1];
/* actually do signal except don't reset SIGILL */
if(args
[1] == (int)SIG_DFL
|| args
[1] & (int)SIG_IGN
) {
if((int)signal(args
[0],args
[1]) == -1)
if((int)signal(args
[0], sigcatch
) == -1)
/* brk is successful unless we run over the stack */
if(args
[0] >= regs
[6]) i
= -1;
/* ignore pwbsys for now */
fprintf(stderr
,"UNAME with %d %d\n",args
[0],args
[1]);
strcpy(args
[0],"pwbname");
fprintf(stderr
,"UDATA with %d %d\n",args
[0],args
[1]);
fprintf(stderr
,"USTAT with %d %d\n",args
[0],args
[1]);
fprintf(stderr
,"UTIME with %d %d\n",args
[0],args
[1]);
fprintf(stderr
,"bad PWBSYS %d\n",args
[3]);
* Many sys calls are easily done here since most
* system call codes are the same on version 6 and 7 UNIX
i
= syscall(code
,args
[0],args
[1],args
[2],args
[3],args
[4]);
/* allow read write access to created files for(IDIS v6 mod) */
/* get actual file mode after create */
/* ensure read/write access to owner */
/* change mode back the way it was */
chmod(args
[0], stat32v
.st_mode
);
fprintf(stderr
," sys val -> 0%o\n",i
);
/* set carry bit if sys error */
/* if not an indirect sys call, adjust the pc */
/* do alternate return on one side of fork */
if(code
== FORK
&& i
!= 0)
/* do the various return value formats */
switch(sysargs
[code
][2]) {
/* normal case only one return value in r0 */
/* return a long in r0 - r1 as in time */
/* return two ints in r0 - r1 as in pipe */
long longrev(l
) long l
; {
/* function to reverse the halves of a long */