|
|
1.1 ! root 1: /* sys4.c 4.10 81/07/04 */ ! 2: ! 3: #include "sys/param.h" ! 4: #include "sys/systm.h" ! 5: #include "sys/user.h" ! 6: #include "sys/inode.h" ! 7: #include "sys/proc.h" ! 8: #include "sys/clock.h" ! 9: #include "sys/timeb.h" ! 10: #include "sys/times.h" ! 11: #include "sys/file.h" ! 12: ! 13: /* ! 14: * Everything in this file is a routine implementing a system call. ! 15: */ ! 16: ! 17: /* ! 18: * return the current time (old-style entry) ! 19: */ ! 20: gtime() ! 21: { ! 22: u.u_r.r_time = time; ! 23: clkcheck(); ! 24: } ! 25: ! 26: /* ! 27: * New time entry-- return TOD with milliseconds, timezone, ! 28: * DST flag ! 29: */ ! 30: ftime() ! 31: { ! 32: register struct a { ! 33: struct timeb *tp; ! 34: } *uap; ! 35: struct timeb t; ! 36: register unsigned ms; ! 37: extern int timezone, dstflag; ! 38: ! 39: uap = (struct a *)u.u_ap; ! 40: (void) spl7(); ! 41: t.time = time; ! 42: ms = lbolt; ! 43: (void) spl0(); ! 44: if (ms > HZ) { ! 45: ms -= HZ; ! 46: t.time++; ! 47: } ! 48: t.millitm = (1000*ms)/HZ; ! 49: t.timezone = timezone; ! 50: t.dstflag = dstflag; ! 51: if (copyout((caddr_t)&t, (caddr_t)uap->tp, sizeof(t))) ! 52: u.u_error = EFAULT; ! 53: clkcheck(); ! 54: } ! 55: ! 56: /* ! 57: * Set the time ! 58: */ ! 59: stime() ! 60: { ! 61: register struct a { ! 62: time_t time; ! 63: } *uap; ! 64: extern time_t bootime; ! 65: ! 66: uap = (struct a *)u.u_ap; ! 67: if(suser()) { ! 68: bootime += uap->time - time; /* silly */ ! 69: time = uap->time; ! 70: clkset(); ! 71: } ! 72: } ! 73: ! 74: setuid() ! 75: { ! 76: register uid; ! 77: register struct a { ! 78: int uid; ! 79: } *uap; ! 80: ! 81: uap = (struct a *)u.u_ap; ! 82: uid = uap->uid; ! 83: if(u.u_ruid == uid || u.u_uid == uid || suser()) { ! 84: u.u_uid = uid; ! 85: u.u_procp->p_uid = uid; ! 86: u.u_ruid = uid; ! 87: } ! 88: } ! 89: ! 90: getuid() ! 91: { ! 92: ! 93: u.u_r.r_val1 = u.u_ruid; ! 94: u.u_r.r_val2 = u.u_uid; ! 95: } ! 96: ! 97: setruid() ! 98: { ! 99: register uid; ! 100: register struct a { ! 101: int uid; ! 102: } *uap; ! 103: ! 104: uap = (struct a *)u.u_ap; ! 105: uid = uap->uid; ! 106: if(suser()) ! 107: u.u_ruid = uid; ! 108: } ! 109: ! 110: setgid() ! 111: { ! 112: register gid; ! 113: register struct a { ! 114: int gid; ! 115: } *uap; ! 116: ! 117: uap = (struct a *)u.u_ap; ! 118: gid = uap->gid; ! 119: if(u.u_rgid == gid || u.u_gid == gid || suser()) { ! 120: u.u_gid = gid; ! 121: u.u_rgid = gid; ! 122: } ! 123: } ! 124: ! 125: getgid() ! 126: { ! 127: ! 128: u.u_r.r_val1 = u.u_rgid; ! 129: u.u_r.r_val2 = u.u_gid; ! 130: } ! 131: ! 132: setgroups() ! 133: { ! 134: register struct a { ! 135: u_int gidsetsize; ! 136: short *gidset; ! 137: } *uap = (struct a *)u.u_ap; ! 138: register short *gp; ! 139: ! 140: if (!suser()) ! 141: return; ! 142: if (uap->gidsetsize > sizeof u.u_groups / sizeof u.u_groups[0]) { ! 143: u.u_error = EINVAL; ! 144: return; ! 145: } ! 146: if (copyin((caddr_t)uap->gidset, (caddr_t)u.u_groups, ! 147: uap->gidsetsize * sizeof u.u_groups[0]) < 0) { ! 148: u.u_error = EFAULT; ! 149: return; ! 150: } ! 151: for (gp = &u.u_groups[uap->gidsetsize] ; gp < &u.u_groups[NGROUPS]; gp++) ! 152: *gp = NOGROUP; ! 153: } ! 154: ! 155: /* ! 156: * Check if gid is a member of the group set. ! 157: */ ! 158: groupmember(gid) ! 159: short gid; ! 160: { ! 161: register short *gp; ! 162: ! 163: if (u.u_gid == gid) ! 164: return (1); ! 165: for (gp = u.u_groups; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++) ! 166: if (*gp == gid) ! 167: return (1); ! 168: return (0); ! 169: } ! 170: ! 171: getgroups() ! 172: { ! 173: register struct a { ! 174: u_int gidsetsize; ! 175: short *gidset; ! 176: } *uap = (struct a *)u.u_ap; ! 177: register short *gp; ! 178: ! 179: for (gp = &u.u_groups[NGROUPS]; gp > u.u_groups; gp--) ! 180: if (gp[-1] != NOGROUP) ! 181: break; ! 182: if (uap->gidsetsize < gp - u.u_groups) { ! 183: u.u_error = EINVAL; ! 184: return; ! 185: } ! 186: uap->gidsetsize = gp - u.u_groups; ! 187: if (copyout((caddr_t)u.u_groups, (caddr_t)uap->gidset, ! 188: uap->gidsetsize * sizeof u.u_groups[0]) < 0) { ! 189: u.u_error = EFAULT; ! 190: return; ! 191: } ! 192: u.u_r.r_val1 = uap->gidsetsize; ! 193: } ! 194: ! 195: getpid() ! 196: { ! 197: u.u_r.r_val1 = u.u_procp->p_pid; ! 198: u.u_r.r_val2 = u.u_procp->p_ppid; ! 199: } ! 200: ! 201: sync() ! 202: { ! 203: ! 204: update(); ! 205: } ! 206: ! 207: nice() ! 208: { ! 209: register n; ! 210: register struct a { ! 211: int niceness; ! 212: } *uap; ! 213: ! 214: uap = (struct a *)u.u_ap; ! 215: n = uap->niceness + u.u_procp->p_nice; ! 216: if(n >= 2*NZERO) ! 217: n = 2*NZERO -1; ! 218: if(n < 0) ! 219: n = 0; ! 220: if (n < u.u_procp->p_nice && !suser()) ! 221: return; ! 222: u.u_procp->p_nice = n; ! 223: } ! 224: ! 225: /* ! 226: * Unlink system call. ! 227: * Hard to avoid races here, especially ! 228: * in unlinking directories. ! 229: */ ! 230: unlink() ! 231: { ! 232: struct a { ! 233: char *fname; ! 234: }; ! 235: struct argnamei nmarg; ! 236: ! 237: nmarg = nilargnamei; ! 238: nmarg.flag = NI_DEL; ! 239: (void) namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nmarg, 0); ! 240: } ! 241: chdir() ! 242: { ! 243: chdirec(&u.u_cdir); ! 244: } ! 245: ! 246: chroot() ! 247: { ! 248: if (suser()) ! 249: chdirec(&u.u_rdir); ! 250: } ! 251: ! 252: chdirec(ipp) ! 253: register struct inode **ipp; ! 254: { ! 255: register struct inode *ip; ! 256: struct a { ! 257: char *fname; ! 258: }; ! 259: ! 260: ip = namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nilargnamei, 1); ! 261: if(ip == NULL) ! 262: return; ! 263: if((ip->i_mode&IFMT) != IFDIR) { ! 264: u.u_error = ENOTDIR; ! 265: goto bad; ! 266: } ! 267: if(access(ip, IEXEC)) ! 268: goto bad; ! 269: prele(ip); ! 270: if (*ipp) { ! 271: plock(*ipp); ! 272: iput(*ipp); ! 273: } ! 274: *ipp = ip; ! 275: return; ! 276: ! 277: bad: ! 278: iput(ip); ! 279: } ! 280: ! 281: fchmod() ! 282: { register struct file *fp; ! 283: register struct a { ! 284: int fd; ! 285: int fmode; ! 286: } *uap; ! 287: ! 288: uap = (struct a *)u.u_ap; ! 289: if((fp = getf(uap->fd)) == NULL) { ! 290: u.u_error = EBADF; ! 291: return; ! 292: } ! 293: chmod1(fp->f_inode, uap->fmode); ! 294: } ! 295: ! 296: chmod() ! 297: { ! 298: register struct inode *ip; ! 299: register struct a { ! 300: char *fname; ! 301: int fmode; ! 302: } *uap; ! 303: ! 304: uap = (struct a *)u.u_ap; ! 305: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL) ! 306: return; ! 307: chmod1(ip, uap->fmode); ! 308: iput(ip); ! 309: } ! 310: ! 311: chmod1(ip, mode) ! 312: register struct inode *ip; ! 313: { ! 314: ! 315: if (accowner(ip) == 0) ! 316: return; ! 317: ip->i_mode &= ~07777; ! 318: if (!(mode&ICONC) && u.u_uid!=0 && !groupmember(ip->i_gid)) ! 319: mode &= ~ISGID; ! 320: ip->i_mode |= mode&07777; ! 321: ip->i_flag |= ICHG; ! 322: } ! 323: ! 324: /* chown with file descriptor*/ ! 325: fchown() ! 326: { register struct file *fp; ! 327: register struct a { ! 328: int fd; ! 329: int uid; ! 330: int gid; ! 331: } *uap; ! 332: ! 333: uap = (struct a *)u.u_ap; ! 334: if((fp = getf(uap->fd)) == NULL) { ! 335: u.u_error = EBADF; ! 336: return; ! 337: } ! 338: chown1(fp->f_inode, uap->uid, uap->gid); ! 339: } ! 340: ! 341: chown() ! 342: { ! 343: register struct inode *ip; ! 344: register struct a { ! 345: char *fname; ! 346: int uid; ! 347: int gid; ! 348: } *uap; ! 349: ! 350: uap = (struct a *)u.u_ap; ! 351: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL) ! 352: return; ! 353: chown1(ip, uap->uid, uap->gid); ! 354: iput(ip); ! 355: } ! 356: ! 357: chown1(ip, uid, gid) ! 358: register struct inode *ip; ! 359: { ! 360: ! 361: if (accowner(ip) == 0) ! 362: return; ! 363: if(u.u_uid){ ! 364: if((ip->i_uid != uid) || !groupmember(gid)){ ! 365: u.u_error = EPERM; ! 366: return; ! 367: } ! 368: if((ip->i_mode&ICONC)==0 && gid != ip->i_gid) ! 369: ip->i_mode &=~ ISGID; ! 370: } ! 371: ip->i_uid = uid; ! 372: ip->i_gid = gid; ! 373: ip->i_flag |= ICHG; ! 374: } ! 375: ! 376: ssig() ! 377: { ! 378: register int (*f)(); ! 379: struct a { ! 380: int signo; ! 381: int (*fun)(); ! 382: } *uap; ! 383: register struct proc *p = u.u_procp; ! 384: register a; ! 385: register long sigmask; ! 386: ! 387: uap = (struct a *)u.u_ap; ! 388: a = uap->signo & SIGNUMMASK; ! 389: f = uap->fun; ! 390: if(a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP) { ! 391: u.u_error = EINVAL; ! 392: return; ! 393: } ! 394: u.u_r.r_val1 = (int)u.u_signal[a]; ! 395: sigmask = SIGMASK(a); ! 396: (void) spl6(); ! 397: if (u.u_signal[a] == SIG_IGN) ! 398: p->p_sig &= ~sigmask; /* never to be seen again */ ! 399: u.u_signal[a] = f; ! 400: if (f == SIG_DFL) ! 401: P_SETDFL(p, sigmask); ! 402: else if (f == SIG_IGN) ! 403: P_SETIGN(p, sigmask); ! 404: else if (f == SIG_HOLD) ! 405: P_SETHOLD(p, sigmask); ! 406: else ! 407: P_SETCATCH(p, sigmask); ! 408: (void) spl0(); ! 409: if (uap->signo & SIGDOPAUSE) ! 410: pause(); ! 411: } ! 412: ! 413: kill() ! 414: { ! 415: register struct a { ! 416: int pid; ! 417: int signo; ! 418: } *uap; ! 419: ! 420: u.u_error = ESRCH; /* default error */ ! 421: uap = (struct a *)u.u_ap; ! 422: if (uap->signo > NSIG || uap->signo < 0) { ! 423: u.u_error = EINVAL; ! 424: return; ! 425: } ! 426: if (uap->pid == -1) ! 427: killall(uap->signo); ! 428: else if(uap->pid > 0) ! 429: killproc(uap->pid, uap->signo); ! 430: else if (uap->pid < 0) ! 431: killpgrp(-uap->pid, uap->signo); ! 432: else ! 433: killpgrp(u.u_procp->p_pgrp, uap->signo); ! 434: } ! 435: ! 436: /* ! 437: * kill a single process ! 438: */ ! 439: killproc(pid, sig) ! 440: register int pid, sig; ! 441: { ! 442: register struct proc *p; ! 443: ! 444: for (p = proc; p < procNPROC; p++) ! 445: if (p->p_stat && p->p_pid == pid) ! 446: break; ! 447: if (p == procNPROC) ! 448: return; ! 449: if (u.u_uid && u.u_uid != p->p_uid) { /* no permission */ ! 450: u.u_error = EPERM; ! 451: return; ! 452: } ! 453: if (sig != 0) /* real signal? */ ! 454: psignal(p, sig); /* yes, send it */ ! 455: u.u_error = 0; ! 456: } ! 457: ! 458: /* ! 459: * Kill all processes within a process group but not system processes. ! 460: * SIGCONT may be sent to any descendants (can you say hack?). ! 461: */ ! 462: killpgrp(pgrp, sig) ! 463: register int pgrp, sig; ! 464: { ! 465: register struct proc *p; ! 466: ! 467: for(p = proc; p < procNPROC; p++) { ! 468: if(p->p_stat == 0) ! 469: continue; /* non-existent */ ! 470: if (p->p_pgrp!=pgrp || p->p_flag&SSYS) ! 471: continue; ! 472: if(u.u_uid != 0 && u.u_uid != p->p_uid && ! 473: (sig != SIGCONT || !inferior(p))) ! 474: continue; ! 475: u.u_error = 0; ! 476: if (sig != 0) /* real signal? */ ! 477: psignal(p, sig); /* yes, send it */ ! 478: } ! 479: } ! 480: ! 481: /* ! 482: * Kill all processes except the system processes and the current process ! 483: */ ! 484: killall(sig) ! 485: register int sig; ! 486: { ! 487: register struct proc *p; ! 488: ! 489: if (!suser()) ! 490: return; ! 491: for(p = proc; p < procNPROC; p++) { ! 492: if(p->p_stat == 0) ! 493: continue; ! 494: if (p->p_flag&SSYS || p==u.u_procp) ! 495: continue; ! 496: u.u_error = 0; ! 497: psignal(p, sig); ! 498: } ! 499: } ! 500: ! 501: times() ! 502: { ! 503: register struct a { ! 504: time_t (*times)[4]; ! 505: } *uap; ! 506: struct tms tms; ! 507: ! 508: tms.tms_utime = u.u_vm.vm_utime; ! 509: tms.tms_stime = u.u_vm.vm_stime; ! 510: tms.tms_cutime = u.u_cvm.vm_utime; ! 511: tms.tms_cstime = u.u_cvm.vm_stime; ! 512: uap = (struct a *)u.u_ap; ! 513: if (copyout((caddr_t)&tms, (caddr_t)uap->times, sizeof(struct tms)) < 0) ! 514: u.u_error = EFAULT; ! 515: } ! 516: ! 517: profil() ! 518: { ! 519: register struct a { ! 520: short *bufbase; ! 521: unsigned bufsize; ! 522: unsigned pcoffset; ! 523: unsigned pcscale; ! 524: } *uap; ! 525: ! 526: uap = (struct a *)u.u_ap; ! 527: u.u_prof.pr_base = uap->bufbase; ! 528: u.u_prof.pr_size = uap->bufsize; ! 529: u.u_prof.pr_off = uap->pcoffset; ! 530: u.u_prof.pr_scale = uap->pcscale; ! 531: } ! 532: ! 533: /* ! 534: * alarm clock signal ! 535: */ ! 536: alarm() ! 537: { ! 538: register struct proc *p; ! 539: register c; ! 540: register struct a { ! 541: int deltat; ! 542: } *uap; ! 543: ! 544: uap = (struct a *)u.u_ap; ! 545: p = u.u_procp; ! 546: c = p->p_clktim; ! 547: if (uap->deltat > 65535L) ! 548: uap->deltat = 65535; ! 549: p->p_clktim = uap->deltat; ! 550: u.u_r.r_val1 = c; ! 551: } ! 552: ! 553: /* ! 554: * indefinite wait. ! 555: * no one should wakeup(&u) ! 556: */ ! 557: pause() ! 558: { ! 559: ! 560: for(;;) ! 561: sleep((caddr_t)&u, PSLEP); ! 562: } ! 563: ! 564: /* ! 565: * mode mask for creation of files ! 566: */ ! 567: umask() ! 568: { ! 569: register struct a { ! 570: int mask; ! 571: } *uap; ! 572: register t; ! 573: ! 574: uap = (struct a *)u.u_ap; ! 575: t = u.u_cmask; ! 576: u.u_cmask = uap->mask & 0777; ! 577: u.u_r.r_val1 = t; ! 578: } ! 579: ! 580: /* ! 581: * Set IUPD and IACC times on file. ! 582: * Can't set ICHG. ! 583: */ ! 584: utime() ! 585: { ! 586: register struct a { ! 587: char *fname; ! 588: time_t *tptr; ! 589: } *uap; ! 590: register struct inode *ip; ! 591: time_t tv[2]; ! 592: ! 593: uap = (struct a *)u.u_ap; ! 594: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL) ! 595: return; ! 596: if (accowner(ip) == 0) { ! 597: iput(ip); ! 598: return; ! 599: } ! 600: if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) { ! 601: u.u_error = EFAULT; ! 602: } else { ! 603: ip->i_flag |= IACC|IUPD|ICHG; ! 604: iupdat(ip, &tv[0], &tv[1], 0); ! 605: } ! 606: iput(ip); ! 607: } ! 608: ! 609: /* ! 610: * Setpgrp on specified process and its descendants. ! 611: * Pid of zero implies current process. ! 612: * Pgrp -1 is getpgrp system call returning ! 613: * current process group. ! 614: */ ! 615: setpgrp() ! 616: { ! 617: register struct proc *top; ! 618: register struct a { ! 619: int pid; ! 620: int pgrp; ! 621: } *uap; ! 622: ! 623: uap = (struct a *)u.u_ap; ! 624: uap->pid = (short)uap->pid; /* else 0x10000 would make pgrp 0 */ ! 625: uap->pgrp = (short)uap->pgrp; ! 626: if (uap->pid == 0) ! 627: top = u.u_procp; ! 628: else { ! 629: top = pfind(uap->pid); ! 630: if (top == 0) { ! 631: u.u_error = ESRCH; ! 632: return; ! 633: } ! 634: } ! 635: if (uap->pgrp == 0 && !suser()) ! 636: return; ! 637: ! 638: if (uap->pgrp < 0) { ! 639: u.u_r.r_val1 = top->p_pgrp; ! 640: return; ! 641: } ! 642: if (top->p_uid != u.u_uid && u.u_uid && !inferior(top)) ! 643: u.u_error = EPERM; ! 644: else ! 645: top->p_pgrp = uap->pgrp; ! 646: } ! 647: ! 648: spgrp(top, npgrp) ! 649: register struct proc *top; ! 650: { ! 651: register struct proc *pp, *p; ! 652: int f = 0; ! 653: ! 654: for (p = top; npgrp == -1 || u.u_uid == p->p_uid || ! 655: !u.u_uid || inferior(p); p = pp) { ! 656: if (npgrp == -1) { ! 657: #define bit(a) (1<<(a-1)) ! 658: p->p_sig &= ~(bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); ! 659: } else ! 660: p->p_pgrp = npgrp; ! 661: f++; ! 662: /* ! 663: * Search for children. ! 664: */ ! 665: for (pp = proc; pp < procNPROC; pp++) ! 666: if (pp->p_stat != 0 && pp->p_pptr == p) ! 667: goto cont; ! 668: /* ! 669: * Search for siblings. ! 670: */ ! 671: for (; p != top; p = p->p_pptr) ! 672: for (pp = p + 1; pp < procNPROC; pp++) ! 673: if (pp->p_stat != 0 && pp->p_pptr == p->p_pptr) ! 674: goto cont; ! 675: break; ! 676: cont: ! 677: ; ! 678: } ! 679: return (f); ! 680: } ! 681: ! 682: /* ! 683: * Is p an inferior of the current process? ! 684: */ ! 685: inferior(p) ! 686: register struct proc *p; ! 687: { ! 688: ! 689: for (; p != u.u_procp; p = p->p_pptr) ! 690: if (p < &proc[SYSPIDS]) ! 691: return (0); ! 692: return (1); ! 693: } ! 694: ! 695: sysboot() ! 696: { ! 697: register struct a { ! 698: int opt; ! 699: }; ! 700: ! 701: if (suser()) ! 702: boot(((struct a *)u.u_ap)->opt); ! 703: } ! 704: ! 705: /* ! 706: * lock user into core as much ! 707: * as possible. swapping may still ! 708: * occur if core grows. ! 709: */ ! 710: syslock() ! 711: { ! 712: register struct proc *p; ! 713: register struct a { ! 714: int flag; ! 715: } *uap; ! 716: ! 717: uap = (struct a *)u.u_ap; ! 718: if(suser()) { ! 719: p = u.u_procp; ! 720: p->p_flag &= ~SULOCK; ! 721: if(uap->flag) ! 722: p->p_flag |= SULOCK; ! 723: } ! 724: } ! 725: ! 726: /* ! 727: * nap for n clock ticks ! 728: */ ! 729: #define MAXNAP 120 ! 730: nap() ! 731: { ! 732: register struct a { ! 733: int nticks; ! 734: } *uap; ! 735: register int n; ! 736: ! 737: uap = (struct a *)u.u_ap; ! 738: n = uap->nticks; ! 739: if (n < 0) ! 740: n = 0; ! 741: if (n > MAXNAP) ! 742: n = MAXNAP; ! 743: delay (n); ! 744: } ! 745: ! 746: /* ! 747: * get/set user's login name ! 748: */ ! 749: ! 750: getlogname() ! 751: { ! 752: register struct a { ! 753: char *name; ! 754: int flag; ! 755: } *uap; ! 756: ! 757: uap = (struct a *)u.u_ap; ! 758: if (uap->flag == 0) { ! 759: if (copyout((caddr_t)u.u_logname, (caddr_t)uap->name, sizeof(u.u_logname)) < 0) ! 760: u.u_error = EFAULT; ! 761: return; ! 762: } ! 763: if (suser() == 0) ! 764: return; ! 765: if (copyin((caddr_t)uap->name, (caddr_t)u.u_logname, sizeof(u.u_logname))) ! 766: u.u_error = EFAULT; ! 767: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.