1*16442Smckusick #ifndef lint 2*16442Smckusick static char sccsid[] = "@(#)unixtraps.c 4.3 84/05/05"; 3*16442Smckusick #endif 414311Ssam 5*16442Smckusick /* From Lou Salkind: compat/RCS/unixtraps.c,v 1.2 84/01/31 13:34:34 */ 6*16442Smckusick 714311Ssam /* 814311Ssam * Function to execute version 6 and version 7 UNIX system calls from 914311Ssam * compatability mode on UNIX-32V. 106809Srrh * Art Wetzel August 1979 116809Srrh */ 1214311Ssam 136809Srrh #include <stdio.h> 146809Srrh #include <signal.h> 156809Srrh #include <sys/types.h> 166809Srrh #include <sys/stat.h> 1714311Ssam #include <sys/ioctl.h> 1814311Ssam #include <sys/time.h> 19*16442Smckusick #include <sys/dir.h> 206809Srrh #ifdef V6UNIX 216809Srrh #ifdef TRACE 226809Srrh #define RTSNAME "/../../../../usr/local/v6trc" 236809Srrh #else 246809Srrh #define RTSNAME "/../../../../usr/local/v6run" 256809Srrh #endif 266809Srrh #include "unix6sys.h" 276809Srrh #ifdef TRACE 286809Srrh #include "unix6sysn.h" 296809Srrh #endif 306809Srrh #endif 316809Srrh #ifdef V7UNIX 326809Srrh #ifdef TRACE 336809Srrh #define RTSNAME "/../../../../usr/local/v7trc" 346809Srrh #else 356809Srrh #define RTSNAME "/../../../../usr/local/v7run" 366809Srrh #endif 376809Srrh #include "unix7sys.h" 386809Srrh #ifdef TRACE 396809Srrh #include "unix7sysn.h" 406809Srrh #endif 416809Srrh #endif 426809Srrh #include "defs.h" 436809Srrh #define CARRY 1 44*16442Smckusick #define MAXSARGS 100 456809Srrh #ifdef V6UNIX 466809Srrh #define ARGVLEN 512 476809Srrh #define ENVLEN 0 486809Srrh #endif 496809Srrh #ifdef V7UNIX 506809Srrh #define ARGVLEN 5120 516809Srrh #define ENVLEN 1000 526809Srrh #endif 536809Srrh char argvs[ARGVLEN+ENVLEN]; 546809Srrh int args[MAXSARGS]; 5514311Ssam 566809Srrh /* 32v type stat structure */ 576809Srrh extern struct stat stat32v; 5814311Ssam 596809Srrh /* place for times data so we can reverse the longs */ 606809Srrh struct timebuf { 616809Srrh long t1; 626809Srrh long t2; 636809Srrh long t3; 646809Srrh long t4; 656809Srrh } timebuf; 6614311Ssam 676809Srrh /* place for pipe file descriptors */ 686809Srrh int pipes[2]; 6914311Ssam 706809Srrh /* wait status */ 716809Srrh int wstatus; 7214311Ssam 736809Srrh #ifdef V6UNIX 746809Srrh /* version 6 style stat structure */ 756809Srrh struct v6nod { 766809Srrh dev_t majmin; 776809Srrh ino_t inumber; 786809Srrh unsigned short flags; 796809Srrh unsigned char nlinks; 806809Srrh unsigned char uid; 816809Srrh unsigned char gid; 826809Srrh unsigned char size0; 836809Srrh unsigned short size1; 846809Srrh unsigned short addr[8]; 856809Srrh long actime; 866809Srrh long modtime; 876809Srrh } *v6stat; 886809Srrh #endif 8914311Ssam 9014311Ssam #ifdef V7UNIX 9114311Ssam /* version 7 style stat structure */ 9214311Ssam struct v7stat { 9314311Ssam dev_t v7st_dev; 9414311Ssam u_short v7st_ino; 9514311Ssam u_short v7st_mode; 9614311Ssam short v7st_nlink; 9714311Ssam short v7st_uid; 9814311Ssam short v7st_gid; 9914311Ssam dev_t v7st_rdev; 10014311Ssam int v7st_size; 10114311Ssam int v7st_atime; 10214311Ssam int v7st_mtime; 10314311Ssam int v7st_ctime; 10414311Ssam } statv7; 10514311Ssam 10614311Ssam struct timeb { 10714311Ssam time_t time; 10814311Ssam u_short millitm; 10914311Ssam short timezone; 11014311Ssam short dstflag; 11114311Ssam } timeb; 11214311Ssam #endif 11314311Ssam 114*16442Smckusick #define NFILES 20 115*16442Smckusick #define ODSIZE 16 116*16442Smckusick 117*16442Smckusick off_t olseek(); 118*16442Smckusick 119*16442Smckusick struct odirect { 120*16442Smckusick u_short od_ino; 121*16442Smckusick char od_name[14]; 122*16442Smckusick }; 123*16442Smckusick 124*16442Smckusick struct fdflags { 125*16442Smckusick DIR *fd_dirp; 126*16442Smckusick struct odirect fd_od; 127*16442Smckusick off_t fd_offset; 128*16442Smckusick } fdflags[NFILES]; 129*16442Smckusick 1306809Srrh /* do the trap stuff for the trap with code */ 13114311Ssam dotrap(code) 13214311Ssam int code; 13314311Ssam { 1346809Srrh register unsigned short *argp, *savp, *savep; 1356809Srrh register int i, j, indirflg; 1366809Srrh register char *avp, *oavp; 1376809Srrh extern sigcatch(); 1386809Srrh extern errno; 139*16442Smckusick extern int sigtrapped; 140*16442Smckusick DIR *dp; 14114311Ssam 142*16442Smckusick sigtrapped = 0; 1436809Srrh /* clear out condition codes of psl */ 1446809Srrh psl &= ~017; 1456809Srrh /* special case of indirect sys call */ 14614311Ssam if (code == 0) { 1476809Srrh /* remember this was indirect */ 1486809Srrh indirflg = 1; 1496809Srrh /* point to args */ 1506809Srrh argp = (unsigned short *)*(pc++); 1516809Srrh /* code for indirect sys call */ 1526809Srrh code = *argp++; 1536809Srrh /* is it legit */ 15414311Ssam if (code>>8 != TRAPS) { 1556809Srrh fprintf(stderr,"Bad indirect sys call at 0x%x\n",pc-2); 1566809Srrh pc++; 1576809Srrh /* set carry flag */ 1586809Srrh psl |= CARRY; 1596809Srrh regs[0] = -1; 1606809Srrh return(-1); 1616809Srrh } 1626809Srrh code &= 0377; 16314311Ssam } else { 1646809Srrh /* remember this was not indirect */ 1656809Srrh indirflg = 0; 1666809Srrh /* point to args */ 1676809Srrh argp = pc; 1686809Srrh } 1696809Srrh /* check if code too high or bad sys code */ 17014311Ssam if (code >= NSYSTRAPS || sysargs[code][0] == ILLSYS) { 1716809Srrh fprintf(stderr,"Unimplimented trap %d at 0x%x\n",code,argp); 1726809Srrh /* set carry bit */ 1736809Srrh psl |= CARRY; 1746809Srrh regs[0] = -1; 1756809Srrh return(-1); 1766809Srrh } 1776809Srrh /* copy args to known locations */ 1786809Srrh i=0; 17914311Ssam for (j=0; j<sysargs[code][0]; j++) 18014311Ssam args[i++] = regs[j]; 18114311Ssam for (j=0; j<(sysargs[code][1]); j++) 18214311Ssam args[i++] = *argp++; 1836809Srrh #ifdef TRACE 1846809Srrh fprintf(stderr,"pid %d ",getpid()); 18514311Ssam if (indirflg) 18614311Ssam fprintf(stderr,"indirect "); 18714311Ssam fprintf(stderr, "%s (%d) from 0%o with %d args", 18814311Ssam sysnames[code], code, pc-1, i); 18914311Ssam for (j=0; j<i; j++) 1906809Srrh fprintf(stderr," 0%o",args[j]); 19114311Ssam if (code==OPEN || code==STAT || code==CREAT || code==EXEC || 19214311Ssam code==UNLNK || code==LINK || code==CHDIR || code==MKNOD) 1936809Srrh fprintf(stderr," (%s)",args[0]); 1946809Srrh #ifdef V7UNIX 19514311Ssam if (code==EXECE) 1966809Srrh fprintf(stderr," (%s)",args[0]); 1976809Srrh #endif 19814311Ssam if (code==LINK) 1996809Srrh fprintf(stderr," (%s)",args[1]); 2006809Srrh #endif 2016809Srrh /* go do whatever sys call it is */ 20214311Ssam switch (code) { 20314311Ssam case FORK: 2046809Srrh /* indirect forks return pids on both sides - must do here */ 2056809Srrh /* this is possibly a bug in 32V */ 2066809Srrh i = fork(); 2076809Srrh break; 20814311Ssam 20914311Ssam case WAIT: 2106809Srrh i = wait(&wstatus); 2116809Srrh args[0] = i; 2126809Srrh args[1] = wstatus; 2136809Srrh break; 21414311Ssam 21514311Ssam case EXEC: 2166809Srrh #ifdef V7UNIX 21714311Ssam case EXECE: 2186809Srrh #endif 2196809Srrh /* 2206809Srrh * have to do a lot of junk here to fix up an argv 2216809Srrh * for execute since (1) the pdp-11 argv consists of 16 2226809Srrh * bit pointers and (2) the argv itself is in the 2236809Srrh * pdp-11 program space where it would get clobbered 2246809Srrh * when a new program is read in and before its 2256809Srrh * argv is set up. 2266809Srrh */ 2276809Srrh avp = &argvs[0]; 2286809Srrh savp = (unsigned short *)args[1]; 2296809Srrh #ifdef V6UNIX 23014311Ssam for (i=1; args[i] = *savp++; i++) 23114311Ssam if (args[i] == 0177777) 23214311Ssam break; 2336809Srrh #ifdef TRACE 23414311Ssam else 23514311Ssam fprintf(stderr,"argv[%d]%s ",i-1,args[i]); 2366809Srrh #endif 2376809Srrh #endif 2386809Srrh #ifdef V7UNIX 2396809Srrh savep = (unsigned short *)args[2]; 24014311Ssam for (i=1; args[i] = *savp++; i++) 2416809Srrh #ifdef TRACE 2426809Srrh fprintf(stderr,"argv[%d]%s ",i-1,args[i]); 2436809Srrh #else 2446809Srrh ; 2456809Srrh #endif 2466809Srrh #endif 24714311Ssam if (stat(args[0], &stat32v)) { 2486809Srrh /* return error here if file does not exist */ 2496809Srrh #ifdef TRACE 2506809Srrh fprintf(stderr," does not exist\n"); 2516809Srrh #endif 2526809Srrh i = -1; 2536809Srrh break; 2546809Srrh } 2556809Srrh /* must have execute permission */ 25614311Ssam if (stat32v.st_mode & (S_IEXEC>>6)) 25714311Ssam goto experm; 25814311Ssam if (stat32v.st_mode & (S_IEXEC>>3)) { 25914311Ssam if (stat32v.st_gid == getegid()) 26014311Ssam goto experm; 26114311Ssam if (geteuid() == 0) 26214311Ssam goto experm; 2636809Srrh } 26414311Ssam if (stat32v.st_mode & S_IEXEC) { 26514311Ssam if (stat32v.st_uid == geteuid()) 26614311Ssam goto experm; 26714311Ssam if (geteuid() == 0) 26814311Ssam goto experm; 2696809Srrh } 2706809Srrh /* return failure if no exec permision allowed */ 2716809Srrh i = -1; 2726809Srrh experm: 2736809Srrh /* can't exec a directory */ 27414311Ssam if ((stat32v.st_mode&S_IFMT) == S_IFDIR) 2756809Srrh i = -1; 27614311Ssam if (i == -1) 27714311Ssam break; 2786809Srrh args[i] = 0; 279*16442Smckusick for (j=1; j<i; j++) { 2806809Srrh oavp = (char *)args[j]; 2816809Srrh args[j] = (int)avp; 28214311Ssam while (*avp++ = *oavp++) 28314311Ssam ; 2846809Srrh } 2856809Srrh #ifdef V7UNIX 28614311Ssam if (code == EXECE) { 28714311Ssam for (j = ++i; args[j] = *savep++; j++) 28814311Ssam ; 289*16442Smckusick for (j = i; oavp = (char *)args[j]; j++) { 2906809Srrh args[j] = (int)avp; 29114311Ssam while (*avp++ = *oavp++) 29214311Ssam ; 2936809Srrh } 2946809Srrh } 2956809Srrh #endif 2966809Srrh /* SETUID and SETGID files must be started with a fresh RTS */ 29714311Ssam if (stat32v.st_mode & S_ISGID || stat32v.st_mode & S_ISUID) { 2986809Srrh /* should add a check here for good magic # in header */ 2996809Srrh args[1] = args[0]; 3006809Srrh args[0] = (int)RTSNAME; 3016809Srrh #ifdef TRACE 3026809Srrh fprintf(stderr," SETUID-GID"); 3036809Srrh #endif 30414311Ssam if (args[i]) 3056809Srrh i = execve(args[0], &args[0], &args[i]); 3066809Srrh else 3076809Srrh i = execv(args[0], &args[0]); 3086809Srrh fprintf(stderr,"can't exec %s\n",RTSNAME); 3096809Srrh break; 3106809Srrh } 3116809Srrh i = execute(args[0], &args[1], &args[i]); 3126809Srrh /* shouldn't get here if exec works */ 3136809Srrh break; 31414311Ssam 31514311Ssam case SEEK: 3166809Srrh #ifdef V6UNIX 3176809Srrh /* fix up negative offsets */ 31814311Ssam if (args[2] != 0 && args[2] != 3) 31914311Ssam if (args[1] >= 32768) 32014311Ssam args[1] -= 65536; 32114311Ssam if (args[2] <= 2) 322*16442Smckusick i = olseek(args[0], args[1], args[2]); 3236809Srrh else 324*16442Smckusick i = olseek(args[0], args[1]*512, args[2]-3); 32514311Ssam if (i != -1) 32614311Ssam i = 0; 3276809Srrh #endif 3286809Srrh #ifdef V7UNIX 329*16442Smckusick i = olseek(args[0], (args[1]<<16)|(args[2]&0177777), args[3]); 3306809Srrh #endif 3316809Srrh break; 33214311Ssam 333*16442Smckusick case MKNOD: 334*16442Smckusick if ((args[1] & S_IFMT) == S_IFDIR) 335*16442Smckusick i = mkdir(args[0], args[1] & 0777); 336*16442Smckusick else { 3376809Srrh #ifdef V6UNIX 338*16442Smckusick /* 339*16442Smckusick * version 6 uses allocated bit which 340*16442Smckusick * means regular file here 341*16442Smckusick */ 342*16442Smckusick if (args[1] & S_IFBLK) 343*16442Smckusick args[1] &= ~S_IFREG; 344*16442Smckusick #endif 345*16442Smckusick i = mknod(args[0], args[1], args[2]); 346*16442Smckusick } 3476809Srrh break; 34814311Ssam 34914311Ssam case PIPE: 3506809Srrh i = pipe(pipes); 3516809Srrh args[0] = pipes[0]; 3526809Srrh args[1] = pipes[1]; 3536809Srrh break; 35414311Ssam 3556809Srrh #ifdef V6UNIX 35614311Ssam case TELL: 3576809Srrh i = lseek(args[0], 0L, 1); 3586809Srrh break; 35914311Ssam 36014311Ssam case STTY: 36114311Ssam i = stty(args[0], args[1]); 36214311Ssam break; 36314311Ssam 36414311Ssam case GTTY: 36514311Ssam i = gtty(args[0], args[1]); 36614311Ssam break; 3676809Srrh #endif 36814311Ssam 369*16442Smckusick /* HAVE TO FAKE THE SIZE OF DIRECTORIES */ 370*16442Smckusick 37114311Ssam case STAT: 37214311Ssam i = stat(args[0], &stat32v); 37314311Ssam goto allstat; 37414311Ssam 37514311Ssam case FSTAT: 3766809Srrh /* do the syscall to a local stat buffer */ 37714311Ssam i = fstat(args[0], &stat32v); 37814311Ssam 37914311Ssam allstat: 3806809Srrh /* reverse the longs */ 3816809Srrh stat32v.st_size = longrev(stat32v.st_size); 3826809Srrh stat32v.st_atime = longrev(stat32v.st_atime); 3836809Srrh stat32v.st_mtime = longrev(stat32v.st_mtime); 3846809Srrh stat32v.st_ctime = longrev(stat32v.st_ctime); 3856809Srrh #ifdef V7UNIX 38614311Ssam statv7.v7st_dev = stat32v.st_dev; 38714311Ssam statv7.v7st_ino = stat32v.st_ino; 38814311Ssam statv7.v7st_mode = stat32v.st_mode; 38914311Ssam statv7.v7st_nlink = stat32v.st_nlink; 39014311Ssam statv7.v7st_uid = stat32v.st_uid; 39114311Ssam statv7.v7st_gid = stat32v.st_gid; 39214311Ssam statv7.v7st_rdev = stat32v.st_rdev; 39314311Ssam statv7.v7st_size = stat32v.st_size; 39414311Ssam statv7.v7st_atime = stat32v.st_atime; 39514311Ssam statv7.v7st_mtime = stat32v.st_mtime; 39614311Ssam statv7.v7st_ctime = stat32v.st_ctime; 3976809Srrh /* copy out otherwise unchanged stat buffer */ 3986809Srrh /* in two pieces with st_size as the breaking point */ 3996809Srrh /* note that st_rdev is a short but due to alingnmemt */ 4006809Srrh /* problems the rest of the structure is out of sync */ 40114311Ssam j = (int)((char *)(&statv7.v7st_size) - 40214311Ssam (char *)(&statv7.v7st_dev)); 40314311Ssam bcopy(&statv7, args[1], j); 40414311Ssam bcopy(&statv7.v7st_size, args[1]+j-2, sizeof(struct v7stat)-j); 4056809Srrh #endif 4066809Srrh #ifdef V6UNIX 4076809Srrh /* point to user area as v6stat structure */ 4086809Srrh v6stat = (struct v6nod *)args[1]; 4096809Srrh /* copy out piece by piece */ 4106809Srrh v6stat->majmin = stat32v.st_dev; 4116809Srrh v6stat->inumber = stat32v.st_ino; 4126809Srrh v6stat->flags = stat32v.st_mode; 4136809Srrh v6stat->nlinks = (unsigned char)stat32v.st_nlink; 4146809Srrh v6stat->uid = (unsigned char)stat32v.st_uid; 4156809Srrh v6stat->gid = (unsigned char)stat32v.st_gid; 4166809Srrh /* note size already reversed */ 4176809Srrh v6stat->size0 = (unsigned char)(stat32v.st_size & 0377); 4186809Srrh v6stat->size1 = (unsigned short)(stat32v.st_size>>16); 4196809Srrh v6stat->actime = stat32v.st_atime; 4206809Srrh v6stat->modtime = stat32v.st_mtime; 4216809Srrh /* patch up flags */ 4226809Srrh /* for now just set 100000 bit if not a plain file */ 42314311Ssam if (v6stat->flags & 060000) 4246809Srrh v6stat->flags |= 0100000; 4256809Srrh #endif 4266809Srrh break; 42714311Ssam 42814311Ssam case TIMES: 4296809Srrh i = times(&timebuf); 4306809Srrh timebuf.t2 = longrev(timebuf.t2) + timebuf.t1; 4316809Srrh timebuf.t3 = longrev(timebuf.t3); 4326809Srrh timebuf.t4 = longrev(timebuf.t4); 4336809Srrh bcopy(&timebuf.t2,args[0],sizeof(struct timebuf)-sizeof(long)); 4346809Srrh break; 43514311Ssam 4366809Srrh #ifdef V6UNIX 43714311Ssam case SLEEP: 4386809Srrh /* do a sleep function - what about pwb which has alarm? */ 4396809Srrh sleep(args[0]); 4406809Srrh break; 4416809Srrh #endif 44214311Ssam 44314311Ssam case GETUID: 4446809Srrh args[0] = getuid(); 4456809Srrh args[1] = geteuid(); 4466809Srrh #ifdef V6UNIX 44714311Ssam i = args[1]<<8 | (args[0] & 0377); 4486809Srrh #endif 4496809Srrh break; 45014311Ssam 45114311Ssam case GETGID: 4526809Srrh args[0] = getgid(); 4536809Srrh args[1] = getegid(); 4546809Srrh #ifdef V6UNIX 45514311Ssam i = args[1]<<8 | (args[0] & 0377); 4566809Srrh #endif 4576809Srrh break; 45814311Ssam 45914311Ssam /* uids and gids are 8 bits in version 6 */ 46014311Ssam case SETUID: 46114311Ssam case SETGID: 4626809Srrh #ifdef V6UNIX 46314311Ssam args[0] &= 0377; 46414311Ssam #endif 46514311Ssam if (code == SETUID) 46614311Ssam i = setuid(args[0]); 46714311Ssam else 46814311Ssam i = setgid(args[0]); 4696809Srrh break; 47014311Ssam 47114311Ssam case SIG: 4726809Srrh /* if it is a good signal code */ 47314311Ssam if (args[0] <= NSIG) { 4746809Srrh /* get the current signal value */ 4756809Srrh i = sigvals[args[0]]; 4766809Srrh /* reset the signal to the new value */ 4776809Srrh sigvals[args[0]] = args[1]; 4786809Srrh /* actually do signal except don't reset SIGILL */ 47914311Ssam if (args[0] != SIGILL) { 48014311Ssam if (args[1] == (int)SIG_DFL || 48114311Ssam args[1] & (int)SIG_IGN) { 48214311Ssam if ((int)signal(args[0],args[1]) == -1) 4836809Srrh i = -1; 4846809Srrh } else { 48514311Ssam if ((int)signal(args[0],sigcatch) == -1) 4866809Srrh i = -1; 4876809Srrh } 4886809Srrh } 48914311Ssam } else 49014311Ssam i = -1; 4916809Srrh break; 49214311Ssam 49314311Ssam case BRK: 4946809Srrh /* brk is successful unless we run over the stack */ 49514311Ssam /* NB: this assumes register usage which need not be used */ 4966809Srrh i = 0; 49714311Ssam if (args[0] >= regs[6]) 49814311Ssam i = -1; 4996809Srrh break; 50014311Ssam 50114311Ssam /* 50214311Ssam * the next bunch are to cope with sys calls removed from 4.2 50314311Ssam */ 50414311Ssam case TIME: 50514311Ssam i = time(0); 50614311Ssam break; 50714311Ssam 50814311Ssam case STIME: { 50914311Ssam struct timeval tv; 51014311Ssam 51114311Ssam tv.tv_usec = 0; 51214311Ssam tv.tv_sec = (args[0] & 0xffff) | ((args[1] & 0xffff) << 16); 51314311Ssam i = settimeofday(&tv); 51414311Ssam break; 51514311Ssam } 51614311Ssam 51714311Ssam case NICE: 51814311Ssam i = nice(args[0]); 51914311Ssam break; 52014311Ssam 52114311Ssam #ifdef V7UNIX 52214311Ssam case ALARM: 52314311Ssam i = alarm(args[0]); 52414311Ssam break; 52514311Ssam 52614311Ssam case PAUSE: 52714311Ssam i = pause(); 52814311Ssam break; 52914311Ssam 53014311Ssam case UTIME: 53114311Ssam i = utime(args[0], args[1]); 53214311Ssam break; 53314311Ssam 53414311Ssam case FTIME: 53514311Ssam i = ftime(&timeb); 53614311Ssam timeb.time = longrev(timeb.time); 53714311Ssam bcopy(&timeb, args[0], sizeof timeb - 2); 53814311Ssam break; 53914311Ssam 54014311Ssam case IOCTL: 54114311Ssam args[1] = mapioctl(args[1]); 54214311Ssam if (args[1] == 0) 54314311Ssam i = -1; 54414311Ssam else 54514311Ssam i = ioctl(args[0], args[1], args[2]); 54614311Ssam break; 54714311Ssam #endif 54814311Ssam 5496809Srrh #ifdef V6UNIX 55014311Ssam case PWBSYS: 5516809Srrh /* ignore pwbsys for now */ 55214311Ssam switch (args[2]) { 55314311Ssam case UNAME: 5546809Srrh #ifdef TRACE 5556809Srrh fprintf(stderr,"UNAME with %d %d\n",args[0],args[1]); 5566809Srrh #endif 5576809Srrh strcpy(args[0],"pwbname"); 5586809Srrh i = 0; 5596809Srrh break; 56014311Ssam 56114311Ssam case UDATA: 5626809Srrh #ifdef TRACE 5636809Srrh fprintf(stderr,"UDATA with %d %d\n",args[0],args[1]); 5646809Srrh #endif 5656809Srrh i = 0; 5666809Srrh break; 56714311Ssam 56814311Ssam case USTAT: 5696809Srrh fprintf(stderr,"USTAT with %d %d\n",args[0],args[1]); 5706809Srrh i = 0; 5716809Srrh break; 57214311Ssam 57314311Ssam case UTIME: 5746809Srrh fprintf(stderr,"UTIME with %d %d\n",args[0],args[1]); 5756809Srrh i = 0; 5766809Srrh break; 5776809Srrh default: 5786809Srrh fprintf(stderr,"bad PWBSYS %d\n",args[3]); 5796809Srrh i = -1; 5806809Srrh break; 5816809Srrh } 5826809Srrh break; 5836809Srrh #endif 58414311Ssam 5856809Srrh default: 5866809Srrh /* 5876809Srrh * Many sys calls are easily done here since most 5886809Srrh * system call codes are the same on version 6 and 7 UNIX 5896809Srrh * as they are here. 5906809Srrh */ 5916809Srrh i = syscall(code,args[0],args[1],args[2],args[3],args[4]); 5926809Srrh #ifdef V6UNIX 59314311Ssam /* allow read write access to created files for (IDIS v6 mod) */ 59414311Ssam if (code==CREAT) { 5956809Srrh /* get actual file mode after create */ 5966809Srrh fstat(i, &stat32v); 5976809Srrh close(i); 5986809Srrh /* ensure read/write access to owner */ 5996809Srrh chmod(args[0], 0644); 6006809Srrh i = open(args[0], 2); 6016809Srrh /* change mode back the way it was */ 6026809Srrh chmod(args[0], stat32v.st_mode); 6036809Srrh } 6046809Srrh #endif 6056809Srrh break; 606*16442Smckusick case OPEN: 607*16442Smckusick /* 608*16442Smckusick * check if we are opening a directory 609*16442Smckusick */ 610*16442Smckusick if (stat(args[0], &stat32v) >= 0 && 611*16442Smckusick ((stat32v.st_mode & S_IFMT) == S_IFDIR) && 612*16442Smckusick ((dp = opendir(args[0])) != NULL)) { 613*16442Smckusick #ifdef DTRACE 614*16442Smckusick fprintf(stderr,"open directory fd %d\n", i); 615*16442Smckusick #endif 616*16442Smckusick i = dp->dd_fd; 617*16442Smckusick fdflags[i].fd_dirp = dp; 618*16442Smckusick fdflags[i].fd_offset = 0; 619*16442Smckusick } else 620*16442Smckusick i = open(args[0], args[1]); 621*16442Smckusick break; 622*16442Smckusick case CLOSE: 623*16442Smckusick i = close(args[0]); 624*16442Smckusick if (i >= 0 && fdflags[args[0]].fd_dirp) { 625*16442Smckusick closedir(fdflags[args[0]].fd_dirp); 626*16442Smckusick fdflags[args[0]].fd_dirp = 0; 627*16442Smckusick } 628*16442Smckusick break; 629*16442Smckusick case READ: 630*16442Smckusick if ((unsigned)args[0] < NFILES && fdflags[args[0]].fd_dirp) 631*16442Smckusick i = oread(args[0], args[1], args[2]); 632*16442Smckusick else 633*16442Smckusick i = read(args[0], args[1], args[2]); 634*16442Smckusick break; 6356809Srrh } 6366809Srrh #ifdef TRACE 6376809Srrh fprintf(stderr," sys val -> 0%o\n",i); 6386809Srrh #endif 6396809Srrh /* set carry bit if sys error */ 64014311Ssam if (i == -1) 6416809Srrh psl |= CARRY; 6426809Srrh /* if not an indirect sys call, adjust the pc */ 643*16442Smckusick if (!indirflg && !sigtrapped) 6446809Srrh pc = argp; 6456809Srrh /* do alternate return on one side of fork */ 64614311Ssam if (code == FORK && i != 0) 6476809Srrh pc++; 6486809Srrh /* do the various return value formats */ 64914311Ssam switch (sysargs[code][2]) { 65014311Ssam case NORMRET: 6516809Srrh /* normal case only one return value in r0 */ 6526809Srrh regs[0] = i; 6536809Srrh break; 65414311Ssam case LONGRET: 6556809Srrh /* return a long in r0 - r1 as in time */ 6566809Srrh regs[1] = i; 6576809Srrh regs[0] = i >> 16; 6586809Srrh break; 65914311Ssam case TWORET: 6606809Srrh /* return two ints in r0 - r1 as in pipe */ 66114311Ssam if (i == -1) 6626809Srrh regs[0] = i; 6636809Srrh else { 6646809Srrh regs[1] = args[1]; 6656809Srrh regs[0] = args[0]; 6666809Srrh } 6676809Srrh break; 6686809Srrh } 66914311Ssam if (i== -1) 6706809Srrh regs[0] = errno; 6716809Srrh } 67214311Ssam 67314311Ssam long 67414311Ssam longrev(l) 67514311Ssam long l; 67614311Ssam { 6776809Srrh /* function to reverse the halves of a long */ 6786809Srrh union { 6796809Srrh long lng; 6806809Srrh short s[2]; 6816809Srrh } u; 6826809Srrh register short t; 6836809Srrh u.lng = l; 6846809Srrh t = u.s[0]; 6856809Srrh u.s[0] = u.s[1]; 6866809Srrh u.s[1] = t; 6876809Srrh return(u.lng); 6886809Srrh } 68914311Ssam 69014311Ssam /* 69114311Ssam * Note: these tables are sorted by 69214311Ssam * ioctl "code" (in ascending order). 69314311Ssam */ 69414311Ssam int fctls[] = { FIOCLEX, FIONCLEX, FIOASYNC, FIONBIO, FIONREAD, 0 }; 69514311Ssam int tctls[] = { 69614311Ssam TIOCGETD, TIOCSETD, TIOCHPCL, TIOCMODG, TIOCMODS, 69714311Ssam TIOCGETP, TIOCSETP, TIOCSETN, TIOCEXCL, TIOCNXCL, 69814311Ssam TIOCFLUSH,TIOCSETC, TIOCGETC, TIOCREMOTE,TIOCMGET, 69914311Ssam TIOCMBIC, TIOCMBIS, TIOCMSET, TIOCSTART,TIOCSTOP, 70014311Ssam TIOCPKT, TIOCNOTTY,TIOCSTI, TIOCOUTQ, TIOCGLTC, 70114311Ssam TIOCSLTC, TIOCSPGRP,TIOCGPGRP,TIOCCDTR, TIOCSDTR, 70214311Ssam TIOCCBRK, TIOCSBRK, TIOCLGET, TIOCLSET, TIOCLBIC, 70314311Ssam TIOCLBIS, 0 70414311Ssam }; 70514311Ssam 70614311Ssam /* 70714311Ssam * Map an old style ioctl command to new. 70814311Ssam */ 70914311Ssam mapioctl(cmd) 71014311Ssam int cmd; 71114311Ssam { 71214311Ssam register int *map, c; 71314311Ssam 71414311Ssam switch ((cmd >> 8) & 0xff) { 71514311Ssam 71614311Ssam case 'f': 71714311Ssam map = fctls; 71814311Ssam break; 71914311Ssam 72014311Ssam case 't': 72114311Ssam map = tctls; 72214311Ssam break; 72314311Ssam 72414311Ssam default: 72514311Ssam return (0); 72614311Ssam } 72714311Ssam while ((c = *map) && (c&0xff) < (cmd&0xff)) 72814311Ssam map++; 72914311Ssam if (c && (c&0xff) == (cmd&0xff)) 73014311Ssam return (c); 73114311Ssam return (0); 73214311Ssam } 733*16442Smckusick 734*16442Smckusick /* 735*16442Smckusick * emulate a read of n bytes on an old style directory 736*16442Smckusick */ 737*16442Smckusick oread(fd, buf, count) 738*16442Smckusick int fd, count; 739*16442Smckusick char *buf; 740*16442Smckusick { 741*16442Smckusick struct fdflags *fp; 742*16442Smckusick struct direct *dp; 743*16442Smckusick DIR *dirp; 744*16442Smckusick struct odirect *odp; 745*16442Smckusick register int nleft = count; 746*16442Smckusick int dir_off; 747*16442Smckusick int i; 748*16442Smckusick 749*16442Smckusick fp = &fdflags[fd]; 750*16442Smckusick dirp = fp->fd_dirp; 751*16442Smckusick odp = &fp->fd_od; 752*16442Smckusick if (dirp == NULL) 753*16442Smckusick return(-1); 754*16442Smckusick dir_off = fp->fd_offset % ODSIZE; 755*16442Smckusick if (dir_off) { 756*16442Smckusick i = ODSIZE - dir_off; 757*16442Smckusick if (nleft < i) 758*16442Smckusick i = nleft; 759*16442Smckusick bcopy((caddr_t)odp + dir_off, buf, i); 760*16442Smckusick fp->fd_offset += i; 761*16442Smckusick if (i == nleft) 762*16442Smckusick return(i); 763*16442Smckusick buf += i; 764*16442Smckusick nleft -= i; 765*16442Smckusick } 766*16442Smckusick while (nleft >= ODSIZE) { 767*16442Smckusick if ((dp = readdir(dirp)) == NULL) 768*16442Smckusick return(count - nleft); 769*16442Smckusick odp->od_ino = dp->d_ino; 770*16442Smckusick strncpy(odp->od_name, dp->d_name, 14); 771*16442Smckusick bcopy((caddr_t)odp, buf, ODSIZE); 772*16442Smckusick fp->fd_offset += ODSIZE; 773*16442Smckusick buf += ODSIZE; 774*16442Smckusick nleft -= ODSIZE; 775*16442Smckusick } 776*16442Smckusick if (nleft > 0) { 777*16442Smckusick if ((dp = readdir(dirp)) == NULL) 778*16442Smckusick return(count - nleft); 779*16442Smckusick odp->od_ino = dp->d_ino; 780*16442Smckusick strncpy(odp->od_name, dp->d_name, 14); 781*16442Smckusick bcopy((caddr_t)odp, buf, nleft); 782*16442Smckusick fp->fd_offset += nleft; 783*16442Smckusick /* nleft = 0; */ 784*16442Smckusick } 785*16442Smckusick return(count); 786*16442Smckusick } 787*16442Smckusick 788*16442Smckusick /* 789*16442Smckusick * emulate the lseek system call 790*16442Smckusick */ 791*16442Smckusick off_t 792*16442Smckusick olseek(fd, n, whence) 793*16442Smckusick int fd, whence; 794*16442Smckusick off_t n; 795*16442Smckusick { 796*16442Smckusick struct fdflags *fp; 797*16442Smckusick char buf[512]; 798*16442Smckusick off_t newpos; 799*16442Smckusick int i, j; 800*16442Smckusick 801*16442Smckusick if ((unsigned)fd >= NFILES) 802*16442Smckusick return(-1); 803*16442Smckusick fp = &fdflags[fd]; 804*16442Smckusick /* 805*16442Smckusick * the system can handle everything 806*16442Smckusick * except directory files 807*16442Smckusick */ 808*16442Smckusick if (fp->fd_dirp == NULL) 809*16442Smckusick return(lseek(fd, n, whence)); 810*16442Smckusick switch (whence) { 811*16442Smckusick case 0: 812*16442Smckusick newpos = n; 813*16442Smckusick break; 814*16442Smckusick case 1: 815*16442Smckusick newpos = fp->fd_offset + n; 816*16442Smckusick break; 817*16442Smckusick case 2: /* not yet implemented */ 818*16442Smckusick default: 819*16442Smckusick return(-1); 820*16442Smckusick } 821*16442Smckusick if (newpos < 0) 822*16442Smckusick return(-1); 823*16442Smckusick if (newpos < fp->fd_offset) { 824*16442Smckusick rewinddir(fdflags[fd].fd_dirp); 825*16442Smckusick fp->fd_offset = 0; 826*16442Smckusick } 827*16442Smckusick i = newpos - fp->fd_offset; 828*16442Smckusick while (i > 0) { 829*16442Smckusick j = i < 512 ? i : 512; 830*16442Smckusick if (oread(fd, buf, j) != j) 831*16442Smckusick break; 832*16442Smckusick i -= j; 833*16442Smckusick } 834*16442Smckusick return(fp->fd_offset); 835*16442Smckusick } 836