1: /*
   2:  *	SCCS id	@(#)syslocal.c	2.1 (Berkeley)	9/4/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/dir.h>
   7: #include <sys/proc.h>
   8: #include <sys/seg.h>
   9: #include <sys/user.h>
  10: #include <sys/systm.h>
  11: #include <sys/inode.h>
  12: #include <sys/ino.h>
  13: #include <sys/file.h>
  14: #include <sys/conf.h>
  15: #ifdef  UCB_QUOTAS
  16: #include <sys/quota.h>
  17: #include <sys/qstat.h>
  18: #include <sys/buf.h>
  19: #endif
  20: #ifdef  UCB_VHANGUP
  21: #include <sys/tty.h>
  22: #endif
  23: #include <sys/autoconfig.h>
  24: #ifdef  UCB_NET
  25: #include <sys/mbuf.h>
  26: #include <sys/protosw.h>
  27: #include <sys/socket.h>
  28: #include <sys/socketvar.h>
  29: #include <sys/ubavar.h>
  30: #include <sys/map.h>
  31: #include "../net/if.h"
  32: #include "../net/in_systm.h"
  33: #endif
  34: 
  35: /*
  36:  * These routines implement local system calls
  37:  */
  38: 
  39: /*
  40:  * nostk -- Set up the process to have no stack segment.
  41:  *	    The process is responsible for the management
  42:  *	    of its own stack, and can thus use the full
  43:  *	    64k byte address space.
  44:  */
  45: 
  46: nostk()
  47: {
  48: #ifndef VIRUS_VFORK
  49:     register size;
  50: 
  51:     size = u.u_procp->p_size - u.u_ssize;
  52:     if(estabur(u.u_tsize, u.u_dsize, 0, u.u_sep, RO))
  53:         return;
  54:     u.u_ssize = 0;
  55:     expand(size);
  56: #else
  57:     if(estabur(u.u_tsize, u.u_dsize, 0, u.u_sep, RO))
  58:         return;
  59:     expand(0,S_STACK);
  60:     u.u_ssize = 0;
  61: #endif
  62: }
  63: 
  64: #if !defined(NONSEPARATE) && defined(NONFP)
  65: /*
  66:  * fetchi -- fetch from user I space
  67:  *	     required because the mfpi instruction
  68:  *	     does not work if current and previous
  69:  *	     are both user.
  70:  */
  71: 
  72: fetchi()
  73: {
  74:     struct a {
  75:         caddr_t iaddr;
  76:     };
  77: 
  78:     u.u_r.r_val1 = fuiword(((struct a *)u.u_ap)->iaddr);
  79: }
  80: #endif
  81: 
  82: #ifdef UCB_QUOTAS
  83: /*
  84:  * quota -- establish or change the quota on a directory
  85:  */
  86: quota()
  87: {
  88:     register struct inode *ip;
  89:     register struct a {
  90:         char    *name;
  91:         daddr_t current;
  92:         daddr_t max;
  93:     } *uap;
  94: 
  95:     if (!suser())
  96:         return;
  97: #ifndef UCB_SYMLINKS
  98:     ip = namei(uchar, LOOKUP);
  99: #else
 100:     ip = namei(uchar, LOOKUP, 1);
 101: #endif
 102:     if (ip == NULL)
 103:         return;
 104:     else
 105:         if ((ip->i_mode & IFMT) != IFQUOT) {
 106:             u.u_error = EACCES;
 107:             return;
 108:         }
 109:     /*
 110: 	 * Round the current up to be a multiple of the
 111: 	 * counting unit.
 112: 	 */
 113:     uap = (struct a *) u.u_ap;
 114: #if QCOUNT==2
 115:     ip->i_un.i_qused = ((uap->current + QCOUNT - 1) >> 1) << 1;
 116: #else
 117:     ip->i_un.i_qused = (uap->current + QCOUNT - 1) / QCOUNT * QCOUNT;
 118: #endif
 119:     ip->i_un.i_qmax = uap->max;
 120:     ip->i_flag |= IUPD|IACC;
 121:     iput(ip);
 122: }
 123: #endif
 124: 
 125: #ifdef UCB_QUOTAS
 126: /*
 127:  * the qfstat system call.
 128:  */
 129: qfstat()
 130: {
 131:     register struct file  *fp;
 132:     register struct a {
 133:         int fdes;
 134:         struct  qstat *sb;
 135:     } *uap;
 136: 
 137:     uap = (struct a *) u.u_ap;
 138:     fp = getf(uap->fdes);
 139:     if(fp == NULL)
 140:         return;
 141:     qstat1(fp->f_inode, uap->sb);
 142: }
 143: 
 144: /*
 145:  * the qstat system call.
 146:  */
 147: qstat()
 148: {
 149:     register struct inode *ip;
 150:     struct a {
 151:         char    *fname;
 152:         struct  qstat *sb;
 153:     };
 154: 
 155: #ifndef UCB_SYMLINKS
 156:     ip = namei(uchar, LOOKUP);
 157: #else
 158:     ip = namei(uchar, LOOKUP, 0);
 159: #endif
 160:     if(ip == (struct inode *) NULL)
 161:         return;
 162:     qstat1(ip, ((struct a *) u.u_ap)->sb);
 163:     iput(ip);
 164: }
 165: 
 166: /*
 167:  * The basic routine for qfstat and qstat:
 168:  * get the inode and pass all of it back.
 169:  */
 170: qstat1(ip, ub)
 171: register struct inode *ip;
 172: struct inode *ub;
 173: {
 174:     register struct dinode *dp;
 175:     register struct buf *bp;
 176:     struct qstat qs, *qp;
 177: 
 178: #ifdef UCB_FSFIX
 179:     iupdat(ip, &time, &time, 0);
 180: #else
 181:     iupdat(ip, &time, &time);
 182: #endif
 183: 
 184:     /*
 185: 	 * first copy from inode table
 186: 	 */
 187:     qp = &qs;
 188:     *((struct inode *) qp) = *ip;
 189: 
 190:     /*
 191: 	 * next the dates in the disk
 192: 	 */
 193:     bp = bread(ip->i_dev, itod(ip->i_number));
 194:     dp = (struct dinode *) mapin(bp);
 195:     dp += itoo(ip->i_number);
 196:     qs.qs_atime = dp->di_atime;
 197:     qs.qs_mtime = dp->di_mtime;
 198:     qs.qs_ctime = dp->di_ctime;
 199:     mapout(bp);
 200:     brelse(bp);
 201:     if (copyout((caddr_t) & qs, (caddr_t) ub, sizeof qs) < 0)
 202:         u.u_error = EFAULT;
 203: }
 204: #endif
 205: 
 206: #ifndef MENLO_JCL
 207: /*
 208:  * killpg -- send all processes the specified
 209:  *	     process group the given signal.
 210:  */
 211: 
 212: killpg()
 213: {
 214:     struct a {
 215:         int pgrp;
 216:         int sig;
 217:     };
 218: 
 219:     killgrp(((struct a *) u.u_ap)->pgrp, ((struct a *) u.u_ap)->sig, 0);
 220: }
 221: #endif
 222: 
 223: #ifdef UCB_SUBM
 224: /*
 225:  * killbkg -- signal processes in the specified group that
 226:  *	      have not been blessed by a submit call
 227:  */
 228: 
 229: killbkg()
 230: {
 231:     struct a {
 232:         int pgrp;
 233:         int sig;
 234:     };
 235: 
 236:     killgrp(((struct a *) u.u_ap)->pgrp, ((struct a *) u.u_ap)->sig, SSUBM);
 237: }
 238: #endif
 239: 
 240: #if defined(UCB_SUBM) || !defined(MENLO_JCL)
 241: /*
 242:  * common code for killpg and killbkg
 243:  *
 244:  * if mask is non-zero, send signal
 245:  * only to processes whose (p_flag & mask)
 246:  * is zero.
 247:  */
 248: 
 249: killgrp(pgrp, sig, mask)
 250: register pgrp;
 251: register sig;
 252: {
 253:     register struct proc *p;
 254:     int count;
 255: 
 256:     if(!suser())
 257:         return;
 258:     count = 0;
 259:     for(p = &proc[2]; p <= maxproc; p++) {
 260:         if(p->p_stat == SZOMB || p->p_pgrp != pgrp)
 261:             continue;
 262: 
 263:         /*
 264: 		 * include following if suser is immune
 265: 		 *
 266: 		if(p->p_uid == 0)
 267: 			continue;
 268: 		 *
 269: 		 */
 270: 
 271:         if(mask && (mask & p->p_flag)) {
 272:             continue;
 273:         }
 274:         count++;
 275:         psignal(p, sig);
 276:     }
 277:     if(count == 0)
 278:         u.u_error = ESRCH;
 279: }
 280: #endif
 281: 
 282: #ifdef  UCB_SUBM
 283: /*
 284:  * submit -- mark the specified process to allow execution after logout
 285:  */
 286: 
 287: submit()
 288: {
 289:     register struct proc *p;
 290: #ifndef MENLO_JCL
 291:     register group;
 292: #endif
 293:     register pid;
 294:     struct a {
 295:         int pid;
 296:     };
 297: 
 298:     pid = ((struct a *) u.u_ap)->pid;
 299: #ifndef MENLO_JCL
 300:     group = u.u_procp->p_pgrp;
 301: #endif
 302:     for(p = &proc[2]; p <= maxproc; p++)
 303:         if(p->p_pid == pid) {
 304: #ifndef MENLO_JCL
 305:             if(p->p_pgrp != group && !suser())
 306:                 return;
 307: #else
 308:             if (p->p_uid != u.u_uid && !suser())
 309:                 return;
 310: #endif
 311:             p->p_flag |= SSUBM;
 312:             return;
 313:         }
 314:     u.u_error = ESRCH;
 315: }
 316: #endif	UCB_SUBM
 317: 
 318: #ifdef  UCB_LOGIN
 319: /*
 320:  * login -- mark a process as a login process,
 321:  *	    and record accounting information.
 322:  */
 323: login()
 324: {
 325:     register i;
 326:     struct a {
 327:         int tslot;
 328:         char    crn[4];
 329:     };
 330: 
 331:     if (suser()) {
 332:         u.u_login = ((struct a *) u.u_ap)->tslot;
 333:         for (i = 0; i < sizeof u.u_crn; i++)
 334:             u.u_crn[i] = ((struct a *) u.u_ap)->crn[i];
 335:     }
 336: }
 337: #endif
 338: 
 339: #ifndef MENLO_JCL
 340: /*
 341:  * establish a new process group
 342:  */
 343: setpgrp()
 344: {
 345:     register struct proc *pp;
 346: 
 347:     if (suser()) {
 348:         pp = u.u_procp;
 349:         pp->p_pgrp = pp->p_pid;
 350:     }
 351: }
 352: #endif
 353: 
 354: #ifdef  UCB_LOAD
 355: /*
 356:  * gldav -- get the load averages
 357:  */
 358: gldav()
 359: {
 360:     extern short avenrun[];
 361:     struct a {
 362:         short   *ptr;
 363:     };
 364: 
 365:     if (copyout( (caddr_t) avenrun, (caddr_t) (((struct a *) u.u_ap)->ptr),
 366:         3 * sizeof(short)) < 0)
 367:         u.u_error = EFAULT;
 368: }
 369: #endif
 370: 
 371: #ifndef NONFP
 372: /*
 373:  * fperr - return floating point error registers
 374:  */
 375: fperr()
 376: {
 377:     u.u_r.r_val1 = u.u_fperr.f_fec;
 378:     u.u_r.r_val2 = u.u_fperr.f_fea;
 379: }
 380: #endif
 381: 
 382: #ifdef  UCB_VHANGUP
 383: /*
 384:  * Revoke access to the current tty by all processes.
 385:  * Used only by the super-user in init
 386:  * to give ``clean'' terminals at login.
 387:  */
 388: vhangup()
 389: {
 390:     if (suser()) {
 391:         if (u.u_ttyp == NULL)
 392:             return;
 393:         forceclose(u.u_ttyd);
 394:         if ((u.u_ttyp->t_state) & ISOPEN)
 395:             gsignal(u.u_ttyp->t_pgrp, SIGHUP);
 396:     }
 397: }
 398: 
 399: forceclose(dev)
 400: dev_t   dev;
 401: {
 402:     register struct file *fp;
 403:     register struct inode *ip;
 404:     register int n = 0;
 405: 
 406:     for (fp = file; fp < fileNFILE; fp++) {
 407: #ifdef  UCB_NET
 408:         if (fp->f_flag & FSOCKET)
 409:             continue;
 410: #endif
 411:         if (fp->f_count == 0)
 412:             continue;
 413:         ip = fp->f_inode;
 414:         if ((ip->i_mode & IFMT) != IFCHR)
 415:             continue;
 416:         if (ip->i_un.i_rdev != dev)
 417:             continue;
 418:         fp->f_flag &= ~(FREAD | FWRITE);
 419:         n++;
 420:     }
 421:     return (n);
 422: }
 423: #endif	UCB_VHANGUP
 424: 
 425: #ifdef  UCB_RENICE
 426: /*
 427:  * renice -- change the nice value of a process
 428:  */
 429: renice()
 430: {
 431:     register struct proc *p;
 432:     register struct a {
 433:         int pid;
 434:         int nice;
 435:     } *uap;
 436: 
 437:     uap = (struct a *) u.u_ap;
 438: 
 439:     for (p = &proc[2]; p <= maxproc; p++)
 440:         if (p->p_pid == uap->pid) {
 441:             if (suser()) {
 442:                 u.u_r.r_val1 = p->p_nice;
 443:                 p->p_nice = MAX(uap->nice, -127);
 444:             }
 445:             else if (p->p_uid == u.u_uid) {
 446:                 u.u_r.r_val1 = p->p_nice;
 447:                 p->p_nice = MIN(MAX(p->p_nice, uap->nice), 127);
 448:                 u.u_error = 0;
 449:             }
 450:             return;
 451:         }
 452:     u.u_error = ESRCH;
 453: }
 454: #endif	UCB_RENICE
 455: 
 456: int conf_int = CONF_MAGIC; /* Used to pass result from int service to probe() */
 457: 
 458: /*
 459:  * Routine to allow user level code to call various internal
 460:  * functions; in configuration it calls for the probe and
 461:  * attach functions of the various drivers.
 462:  */
 463: ucall()
 464: {
 465:     register struct a {
 466:         int priority;
 467:         int (*routine)();
 468:         int arg0;
 469:         int arg1;
 470:     } *uap;
 471: 
 472:     if (suser()) {
 473:         uap = (struct a *) u.u_ap;
 474:         (void) splx(uap->priority);
 475:         u.u_r.r_val1 = (*uap->routine)(uap->arg0, uap->arg1);
 476:         (void) _spl0();
 477:     }
 478: }
 479: 
 480: #ifdef  UCB_NET
 481: 
 482: extern  u_long LocalAddr;   /* Generic local net address	*/
 483: 
 484: int nlbase;         /* net error log area in clicks */
 485: int nlsize = 01000;
 486: int nlclick, nlbyte;
 487: 
 488: int netoff = 0;
 489: int protoslow;
 490: int protofast;
 491: int ifnetslow;
 492: int nselcoll;
 493: 
 494: /*
 495:  * Initialize network code.  Called from main().
 496:  */
 497: netinit()
 498: {
 499:     extern struct uba_device ubdinit[];
 500:     register struct uba_driver *udp;
 501:     register struct uba_device *ui = &ubdinit;
 502: 
 503:     if (netoff)
 504:         return;
 505:     nlbase = nlclick = malloc(coremap, nlsize);  /* net error log */
 506:     MAPSAVE();
 507:     mbinit();
 508:     for (ui = &ubdinit ; udp = ui->ui_driver ; ui++) {
 509:         if (badaddr(ui->ui_addr, 2))
 510:             continue;
 511:         ui->ui_alive = 1;
 512:         udp->ud_dinfo[ui->ui_unit] = ui;
 513:         (*udp->ud_attach)(ui);
 514:     }
 515: #ifdef INET
 516:     loattach();         /* XXX */
 517:     ifinit();
 518:     pfinit();           /* must follow interfaces */
 519: #endif
 520:     MAPREST();
 521: }
 522: 
 523: /*
 524:  * Entered via software interrupt vector at spl1.  Check netisr bit array
 525:  * for tasks requesting service.
 526:  */
 527: netintr()
 528: {
 529:     int onetisr;
 530:     mapinfo map;
 531: 
 532:     savemap(map);
 533:     while (spl7(), (onetisr = netisr)) {
 534:         netisr = 0;
 535:         splnet();
 536:         if (onetisr & (1 << NETISR_RAW))
 537:             rawintr();
 538:         if (onetisr & (1 << NETISR_IP))
 539:             ipintr();
 540:         if (protofast <= 0) {
 541:             protofast = hz / PR_FASTHZ;
 542:             pffasttimo();
 543:         }
 544:         if (protoslow <= 0) {
 545:             protoslow = hz / PR_SLOWHZ;
 546:             pfslowtimo();
 547:         }
 548:         if (ifnetslow <= 0) {
 549:             ifnetslow = hz / IFNET_SLOWHZ;
 550:             if_slowtimo();
 551:         }
 552:     }
 553:     restormap(map);
 554: }
 555: 
 556: int nprint = 0;            /* enable nprintf */
 557: 
 558: /*
 559:  * net printf.  prints to net log area in memory (nlbase, nlsize).
 560:  */
 561: nprintf(fmt, x1)
 562: char *fmt;
 563: unsigned x1;
 564: {
 565:     if (enprint)
 566:         prf(fmt, &x1, 4);
 567: }
 568: 
 569: /*
 570:  * Select system call.
 571:  */
 572: select()
 573: {
 574:     register struct uap  {
 575:         int nfd;
 576:         fd_set  *rp, *wp;
 577:         long    timo;
 578:     } *ap = (struct uap *)u.u_ap;
 579:     fd_set rd, wr;
 580:     int nfds = 0;
 581:     long selscan();
 582:     long readable = 0, writeable = 0;
 583:     time_t t = time;
 584:     int s, tsel, ncoll, rem;
 585: 
 586:     if (ap->nfd > NOFILE)
 587:         ap->nfd = NOFILE;
 588:     if (ap->nfd < 0) {
 589:         u.u_error = EBADF;
 590:         return;
 591:     }
 592:     if (ap->rp && copyin((caddr_t)ap->rp, (caddr_t)&rd, sizeof(fd_set)))
 593:         return;
 594:     if (ap->wp && copyin((caddr_t)ap->wp, (caddr_t)&wr, sizeof(fd_set)))
 595:         return;
 596: 
 597: retry:
 598:     ncoll = nselcoll;
 599:     u.u_procp->p_flag |= SSEL;
 600:     if (ap->rp)
 601:         readable = selscan(ap->nfd, rd, &nfds, FREAD);
 602:     if (ap->wp)
 603:         writeable = selscan(ap->nfd, wr, &nfds, FWRITE);
 604:     if (u.u_error)
 605:         goto done;
 606:     if (readable || writeable)
 607:         goto done;
 608:     rem = (ap->timo + 999) / 1000 - (time - t);
 609:     if (ap->timo == 0 || rem <= 0)
 610:         goto done;
 611:     s = spl6();
 612:     if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
 613:         u.u_procp->p_flag &= ~SSEL;
 614:         splx(s);
 615:         goto retry;
 616:     }
 617:     u.u_procp->p_flag &= ~SSEL;
 618:     tsel = tsleep((caddr_t)&selwait, PZERO + 1, rem);
 619:     splx(s);
 620:     switch (tsel) {
 621: 
 622:         case TS_OK:
 623:             goto retry;
 624: 
 625:         case TS_SIG:
 626:             u.u_error = EINTR;
 627:             return;
 628: 
 629:         case TS_TIME:
 630:             break;
 631:     }
 632: done:
 633:     rd.fds_bits[0] = readable;
 634:     wr.fds_bits[0] = writeable;
 635:     s = sizeof (fd_set);
 636:     if (s * NBBY > ap->nfd)
 637:         s = (ap->nfd + NBBY - 1) / NBBY;
 638:     u.u_r.r_val1 = nfds;
 639:     if (ap->rp)
 640:         (void) copyout((caddr_t)&rd, (caddr_t)ap->rp, sizeof(fd_set));
 641:     if (ap->wp)
 642:         (void) copyout((caddr_t)&wr, (caddr_t)ap->wp, sizeof(fd_set));
 643: }
 644: 
 645: long
 646: selscan(nfd, fds, nfdp, flag)
 647:     int nfd;
 648:     fd_set fds;
 649:     int *nfdp, flag;
 650: {
 651:     struct file *fp;
 652:     struct inode *ip;
 653:     long bits,res = 0;
 654:     int i, able;
 655: 
 656:     bits = fds.fds_bits[0];
 657:     while (i = ffs(bits)) {
 658:         if (i >= nfd)
 659:             break;
 660:         bits &= ~(1L << (i - 1));
 661:         fp = u.u_ofile[i - 1];
 662:         if (fp == NULL) {
 663:             u.u_error = EBADF;
 664:             return (0);
 665:         }
 666:         if (fp->f_flag & FSOCKET)
 667:             able = soselect(fp->f_socket, flag);
 668:         else {
 669:             ip = fp->f_inode;
 670:             switch (ip->i_mode & IFMT) {
 671: 
 672:                 case IFCHR:
 673:                     able = (*cdevsw[major(ip->i_un.i_rdev)].d_select)
 674:                         ((int)ip->i_un.i_rdev, flag);
 675:                     break;
 676: 
 677:                 case IFBLK:
 678:                 case IFREG:
 679:                 case IFDIR:
 680:                     able = 1;
 681:                     break;
 682:             }
 683:         }
 684:         if (able) {
 685:             res |= (1L << (i - 1));
 686:             (*nfdp)++;
 687:         }
 688:     }
 689:     return (res);
 690: }
 691: 
 692: ffs(mask)
 693:     long mask;
 694: {
 695:     register int i;
 696:     register imask;
 697: 
 698:     if (mask == 0)
 699:         return (0);
 700: 
 701:     imask = loint(mask);
 702:     for (i = 1; i < 16; i++) {
 703:         if (imask & 1)
 704:             return (i);
 705:         imask >>= 1;
 706:     }
 707:     imask = hiint(mask);
 708:     for(; i <= 32; i++) {
 709:         if (imask & 1)
 710:             return (i);
 711:         imask >>= 1;
 712:     }
 713:     return (0);     /* can't get here anyway! */
 714: }
 715: 
 716: /*ARGSUSED*/
 717: seltrue(dev, flag)
 718:     dev_t dev;
 719:     int flag;
 720: {
 721:     return (1);
 722: }
 723: 
 724: selwakeup(p, coll)
 725:     register struct proc *p;
 726:     int coll;
 727: {
 728:     int s;
 729: 
 730:     if (coll) {
 731:         nselcoll++;
 732:         wakeup((caddr_t) &selwait);
 733:     }
 734:     s = spl6();
 735:     if (p)
 736:         if (p->p_wchan == (caddr_t) &selwait)
 737:             setrun(p);
 738:         else
 739:             if (p->p_flag & SSEL)
 740:                 p->p_flag &= ~SSEL;
 741:     splx(s);
 742: }
 743: 
 744: char    hostname[32] = "hostnameunknown";
 745: int hostnamelen = 16;
 746: 
 747: gethostname()
 748: {
 749:     register struct a {
 750:         char    *hostname;
 751:         int len;
 752:     } *uap = (struct a *) u.u_ap;
 753:     register int len;
 754: 
 755:     len = uap->len;
 756:     if (len > hostnamelen)
 757:         len = hostnamelen;
 758:     if (copyout((caddr_t) hostname, (caddr_t) uap->hostname, len))
 759:         u.u_error = EFAULT;
 760: }
 761: 
 762: sethostname()
 763: {
 764:     register struct a {
 765:         char    *hostname;
 766:         int len;
 767:     } *uap = (struct a *) u.u_ap;
 768: 
 769:     if (suser()) {
 770:         if (uap->len > sizeof (hostname) - 1) {
 771:             u.u_error = EINVAL;
 772:             return;
 773:         }
 774:         hostnamelen = uap->len;
 775:         if (copyin((caddr_t) uap->hostname, hostname, uap->len + 1))
 776:             u.u_error = EFAULT;
 777:     }
 778: }
 779: 
 780: /*
 781:  * Sleep on chan at pri.
 782:  * Return in no more than the indicated number of seconds.
 783:  * (If seconds==0, no timeout implied)
 784:  * Return	TS_OK if chan was awakened normally
 785:  *		TS_TIME if timeout occurred
 786:  *		TS_SIG if asynchronous signal occurred
 787:  *
 788:  * SHOULD HAVE OPTION TO SLEEP TO ABSOLUTE TIME OR AN
 789:  * INCREMENT IN MILLISECONDS!
 790:  */
 791: tsleep(chan, pri, seconds)
 792:     caddr_t chan;
 793:     int pri, seconds;
 794: {
 795:     label_t lqsav;
 796:     register struct proc *pp;
 797:     register sec, n, rval;
 798: 
 799:     pp = u.u_procp;
 800:     n = spl7();
 801:     sec = 0;
 802:     rval = 0;
 803:     if (pp->p_clktim && pp->p_clktim < seconds)
 804:         seconds = 0;
 805:     if (seconds) {
 806:         pp->p_flag |= STIMO;
 807:         sec = pp->p_clktim - seconds;
 808:         pp->p_clktim = seconds;
 809:     }
 810:     bcopy((caddr_t) u.u_qsav, (caddr_t) lqsav, sizeof (label_t));
 811:     if (save(u.u_qsav))
 812:         rval = TS_SIG;
 813:     else {
 814:         sleep(chan, pri);
 815:         if ((pp->p_flag & STIMO) == 0 && seconds)
 816:             rval = TS_TIME;
 817:         else
 818:             rval = TS_OK;
 819:     }
 820:     pp->p_flag &= ~STIMO;
 821:     bcopy((caddr_t) lqsav, (caddr_t) u.u_qsav, sizeof (label_t));
 822:     if (sec > 0)
 823:         pp->p_clktim += sec;
 824:     else
 825:         pp->p_clktim = 0;
 826:     splx(n);
 827:     return (rval);
 828: }
 829: 
 830: /*
 831:  * Provide about n microseconds of delay
 832:  */
 833: delay(n)
 834: long n;
 835: {
 836:     register hi,low;
 837: 
 838:     low = (n & 0177777);
 839:     hi = n >> 16;
 840:     if (hi == 0)
 841:         hi = 1;
 842:     do {
 843:         do { } while (--low);
 844:     } while(--hi);
 845: }
 846: 
 847: /*
 848:  * compare bytes; same result as VAX cmpc3.
 849:  */
 850: bcmp(s1, s2, n)
 851: register char *s1, *s2;
 852: register n;
 853: {
 854:     do
 855:         if (*s1++ != *s2++)
 856:             break;
 857:     while (--n);
 858: 
 859:     return(n);
 860: }
 861: 
 862: struct  vaxque {        /* queue format expected by VAX queue instr's */
 863:     struct  vaxque  *vq_next;
 864:     struct  vaxque  *vq_prev;
 865: };
 866: 
 867: /*
 868:  * Insert an entry onto queue.
 869:  */
 870: _insque(e,prev)
 871:     register struct vaxque *e,*prev;
 872: {
 873:     e->vq_prev = prev;
 874:     e->vq_next = prev->vq_next;
 875:     prev->vq_next->vq_prev = e;
 876:     prev->vq_next = e;
 877: }
 878: 
 879: /*
 880:  * Remove an entry from queue.
 881:  */
 882: _remque(e)
 883:     register struct vaxque *e;
 884: {
 885:     e->vq_prev->vq_next = e->vq_next;
 886:     e->vq_next->vq_prev = e->vq_prev;
 887: }
 888: 
 889: setreuid()
 890: {
 891:     struct a {
 892:         int ruid;
 893:         int euid;
 894:     } *uap;
 895:     register int ruid, euid;
 896: 
 897:     uap = (struct a *) u.u_ap;
 898:     ruid = uap->ruid;
 899:     if (ruid == -1)
 900:         ruid = u.u_ruid;
 901:     if (u.u_ruid != ruid && u.u_uid != ruid && !suser())
 902:         return;
 903:     euid = uap->euid;
 904:     if (euid == -1)
 905:         euid = u.u_uid;
 906:     if (u.u_ruid != euid && u.u_uid != euid && !suser())
 907:         return;
 908:     /*
 909: 	 * Everything's okay, do it.
 910: 	 */
 911:     u.u_procp->p_uid = ruid;
 912:     u.u_ruid = ruid;
 913:     u.u_uid = euid;
 914: }
 915: 
 916: setregid()
 917: {
 918:     register struct a {
 919:         int rgid;
 920:         int egid;
 921:     } *uap;
 922:     register int rgid, egid;
 923: 
 924:     uap = (struct a *) u.u_ap;
 925:     rgid = uap->rgid;
 926:     if (rgid == -1)
 927:         rgid = u.u_rgid;
 928:     if (u.u_rgid != rgid && u.u_gid != rgid && !suser())
 929:         return;
 930:     egid = uap->egid;
 931:     if (egid == -1)
 932:         egid = u.u_gid;
 933:     if (u.u_rgid != egid && u.u_gid != egid && !suser())
 934:         return;
 935:     if (u.u_rgid != rgid)
 936:         u.u_rgid = rgid;
 937:     if (u.u_gid != egid)
 938:         u.u_gid = egid;
 939: }
 940: 
 941: /*
 942:  *	Get/Set our local internet address.
 943:  *	Names changed from Vax code because of PDP11 length restrictions
 944:  */
 945: gethostid()
 946: {
 947:     u.u_r.r_off = (off_t) LocalAddr;
 948: }
 949: 
 950: sethostid()
 951: {
 952:     struct a {
 953:         u_long  hostid;
 954:     } *uap = (struct a *) u.u_ap;
 955: 
 956:     if (suser())
 957:         LocalAddr = uap->hostid;
 958: }
 959: #endif	UCB_NET

Defined functions

_insque defined in line 870; never used
_remque defined in line 882; never used
bcmp defined in line 850; never used
delay defined in line 833; never used
fetchi defined in line 72; never used
ffs defined in line 692; used 1 times
forceclose defined in line 399; used 1 times
fperr defined in line 375; never used
gethostid defined in line 945; never used
gethostname defined in line 747; never used
gldav defined in line 358; never used
killbkg defined in line 229; never used
killgrp defined in line 249; used 2 times
killpg defined in line 212; never used
login defined in line 323; never used
netinit defined in line 497; used 1 times
netintr defined in line 527; used 2 times
nostk defined in line 46; used 2 times
nprintf defined in line 561; never used
qfstat defined in line 129; never used
qstat defined in line 147; never used
qstat1 defined in line 170; used 2 times
quota defined in line 86; never used
renice defined in line 429; never used
select defined in line 572; never used
selscan defined in line 645; used 3 times
seltrue defined in line 717; never used
selwakeup defined in line 724; used 4 times
sethostid defined in line 950; never used
sethostname defined in line 762; never used
setpgrp defined in line 343; never used
setregid defined in line 916; never used
setreuid defined in line 889; never used
submit defined in line 287; never used
tsleep defined in line 791; used 1 times
ucall defined in line 463; used 2 times
vhangup defined in line 388; never used

Defined variables

conf_int defined in line 456; used 6 times
hostname defined in line 744; used 7 times
hostnamelen defined in line 745; used 3 times
ifnetslow defined in line 491; used 2 times
netoff defined in line 488; used 1 times
nlbase defined in line 484; used 1 times
nlbyte defined in line 486; never used
nlclick defined in line 486; used 1 times
nlsize defined in line 485; used 1 times
nprint defined in line 556; never used
nselcoll defined in line 492; used 3 times
protofast defined in line 490; used 2 times
protoslow defined in line 489; used 2 times

Defined struct's

a defined in line 952; used 38 times
uap defined in line 574; used 2 times
  • in line 578(2)
vaxque defined in line 862; used 8 times
Last modified: 1984-02-19
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2323
Valid CSS Valid XHTML 1.0 Strict