|
|
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: iupdat(ip, &time, &time, 0); ! 323: } ! 324: ! 325: /* chown with file descriptor*/ ! 326: fchown() ! 327: { register struct file *fp; ! 328: register struct a { ! 329: int fd; ! 330: int uid; ! 331: int gid; ! 332: } *uap; ! 333: ! 334: uap = (struct a *)u.u_ap; ! 335: if((fp = getf(uap->fd)) == NULL) { ! 336: u.u_error = EBADF; ! 337: return; ! 338: } ! 339: chown1(fp->f_inode, uap->uid, uap->gid); ! 340: } ! 341: ! 342: chown() ! 343: { ! 344: register struct inode *ip; ! 345: register struct a { ! 346: char *fname; ! 347: int uid; ! 348: int gid; ! 349: } *uap; ! 350: ! 351: uap = (struct a *)u.u_ap; ! 352: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL) ! 353: return; ! 354: chown1(ip, uap->uid, uap->gid); ! 355: iput(ip); ! 356: } ! 357: ! 358: chown1(ip, uid, gid) ! 359: register struct inode *ip; ! 360: { ! 361: ! 362: if (accowner(ip) == 0) ! 363: return; ! 364: if(u.u_uid){ ! 365: if((ip->i_uid != uid) || !groupmember(gid)){ ! 366: u.u_error = EPERM; ! 367: return; ! 368: } ! 369: if((ip->i_mode&ICONC)==0 && gid != ip->i_gid) ! 370: ip->i_mode &=~ ISGID; ! 371: } ! 372: ip->i_uid = uid; ! 373: ip->i_gid = gid; ! 374: ip->i_flag |= ICHG; ! 375: iupdat(ip, &time, &time, 0); ! 376: } ! 377: ! 378: ssig() ! 379: { ! 380: register int (*f)(); ! 381: struct a { ! 382: int signo; ! 383: int (*fun)(); ! 384: } *uap; ! 385: register struct proc *p = u.u_procp; ! 386: register a; ! 387: register long sigmask; ! 388: ! 389: uap = (struct a *)u.u_ap; ! 390: a = uap->signo & SIGNUMMASK; ! 391: f = uap->fun; ! 392: if(a<=0 || a>=NSIG || a==SIGKILL || a==SIGSTOP) { ! 393: u.u_error = EINVAL; ! 394: return; ! 395: } ! 396: u.u_r.r_val1 = (int)u.u_signal[a]; ! 397: sigmask = SIGMASK(a); ! 398: (void) spl6(); ! 399: if (u.u_signal[a] == SIG_IGN) ! 400: p->p_sig &= ~sigmask; /* never to be seen again */ ! 401: u.u_signal[a] = f; ! 402: if (f == SIG_DFL) ! 403: P_SETDFL(p, sigmask); ! 404: else if (f == SIG_IGN) ! 405: P_SETIGN(p, sigmask); ! 406: else if (f == SIG_HOLD) ! 407: P_SETHOLD(p, sigmask); ! 408: else ! 409: P_SETCATCH(p, sigmask); ! 410: (void) spl0(); ! 411: if (uap->signo & SIGDOPAUSE) ! 412: pause(); ! 413: } ! 414: ! 415: kill() ! 416: { ! 417: register struct a { ! 418: int pid; ! 419: int signo; ! 420: } *uap; ! 421: ! 422: u.u_error = ESRCH; /* default error */ ! 423: uap = (struct a *)u.u_ap; ! 424: if (uap->signo > NSIG || uap->signo < 0) { ! 425: u.u_error = EINVAL; ! 426: return; ! 427: } ! 428: if (uap->pid == -1) ! 429: killall(uap->signo); ! 430: else if(uap->pid > 0) ! 431: killproc(uap->pid, uap->signo); ! 432: else if (uap->pid < 0) ! 433: killpgrp(-uap->pid, uap->signo); ! 434: else ! 435: killpgrp(u.u_procp->p_pgrp, uap->signo); ! 436: } ! 437: ! 438: /* ! 439: * kill a single process ! 440: */ ! 441: killproc(pid, sig) ! 442: register int pid, sig; ! 443: { ! 444: register struct proc *p; ! 445: ! 446: for (p = proc; p < procNPROC; p++) ! 447: if (p->p_stat && p->p_pid == pid) ! 448: break; ! 449: if (p == procNPROC) ! 450: return; ! 451: if (u.u_uid && u.u_uid != p->p_uid) { /* no permission */ ! 452: u.u_error = EPERM; ! 453: return; ! 454: } ! 455: if (sig != 0) /* real signal? */ ! 456: psignal(p, sig); /* yes, send it */ ! 457: u.u_error = 0; ! 458: } ! 459: ! 460: /* ! 461: * Kill all processes within a process group but not system processes. ! 462: * SIGCONT may be sent to any descendants (can you say hack?). ! 463: */ ! 464: killpgrp(pgrp, sig) ! 465: register int pgrp, sig; ! 466: { ! 467: register struct proc *p; ! 468: ! 469: for(p = proc; p < procNPROC; p++) { ! 470: if(p->p_stat == 0) ! 471: continue; /* non-existent */ ! 472: if (p->p_pgrp!=pgrp || p->p_flag&SSYS) ! 473: continue; ! 474: if(u.u_uid != 0 && u.u_uid != p->p_uid && ! 475: (sig != SIGCONT || !inferior(p))) ! 476: continue; ! 477: u.u_error = 0; ! 478: if (sig != 0) /* real signal? */ ! 479: psignal(p, sig); /* yes, send it */ ! 480: } ! 481: } ! 482: ! 483: /* ! 484: * Kill all processes except the system processes and the current process ! 485: */ ! 486: killall(sig) ! 487: register int sig; ! 488: { ! 489: register struct proc *p; ! 490: ! 491: if (!suser()) ! 492: return; ! 493: for(p = proc; p < procNPROC; p++) { ! 494: if(p->p_stat == 0) ! 495: continue; ! 496: if (p->p_flag&SSYS || p==u.u_procp) ! 497: continue; ! 498: u.u_error = 0; ! 499: psignal(p, sig); ! 500: } ! 501: } ! 502: ! 503: times() ! 504: { ! 505: register struct a { ! 506: time_t (*times)[4]; ! 507: } *uap; ! 508: struct tms tms; ! 509: ! 510: tms.tms_utime = u.u_vm.vm_utime; ! 511: tms.tms_stime = u.u_vm.vm_stime; ! 512: tms.tms_cutime = u.u_cvm.vm_utime; ! 513: tms.tms_cstime = u.u_cvm.vm_stime; ! 514: uap = (struct a *)u.u_ap; ! 515: if (copyout((caddr_t)&tms, (caddr_t)uap->times, sizeof(struct tms)) < 0) ! 516: u.u_error = EFAULT; ! 517: } ! 518: ! 519: profil() ! 520: { ! 521: register struct a { ! 522: short *bufbase; ! 523: unsigned bufsize; ! 524: unsigned pcoffset; ! 525: unsigned pcscale; ! 526: } *uap; ! 527: ! 528: uap = (struct a *)u.u_ap; ! 529: u.u_prof.pr_base = uap->bufbase; ! 530: u.u_prof.pr_size = uap->bufsize; ! 531: u.u_prof.pr_off = uap->pcoffset; ! 532: u.u_prof.pr_scale = uap->pcscale; ! 533: } ! 534: ! 535: /* ! 536: * alarm clock signal ! 537: */ ! 538: alarm() ! 539: { ! 540: register struct proc *p; ! 541: register c; ! 542: register struct a { ! 543: int deltat; ! 544: } *uap; ! 545: ! 546: uap = (struct a *)u.u_ap; ! 547: p = u.u_procp; ! 548: c = p->p_clktim; ! 549: if (uap->deltat > 65535L) ! 550: uap->deltat = 65535; ! 551: p->p_clktim = uap->deltat; ! 552: u.u_r.r_val1 = c; ! 553: } ! 554: ! 555: /* ! 556: * indefinite wait. ! 557: * no one should wakeup(&u) ! 558: */ ! 559: pause() ! 560: { ! 561: ! 562: for(;;) ! 563: sleep((caddr_t)&u, PSLEP); ! 564: } ! 565: ! 566: /* ! 567: * mode mask for creation of files ! 568: */ ! 569: umask() ! 570: { ! 571: register struct a { ! 572: int mask; ! 573: } *uap; ! 574: register t; ! 575: ! 576: uap = (struct a *)u.u_ap; ! 577: t = u.u_cmask; ! 578: u.u_cmask = uap->mask & 0777; ! 579: u.u_r.r_val1 = t; ! 580: } ! 581: ! 582: /* ! 583: * Set IUPD and IACC times on file. ! 584: * Can't set ICHG. ! 585: */ ! 586: utime() ! 587: { ! 588: register struct a { ! 589: char *fname; ! 590: time_t *tptr; ! 591: } *uap; ! 592: register struct inode *ip; ! 593: time_t tv[2]; ! 594: ! 595: uap = (struct a *)u.u_ap; ! 596: if ((ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1)) == NULL) ! 597: return; ! 598: if (accowner(ip) == 0) { ! 599: iput(ip); ! 600: return; ! 601: } ! 602: if (copyin((caddr_t)uap->tptr, (caddr_t)tv, sizeof(tv))) { ! 603: u.u_error = EFAULT; ! 604: } else { ! 605: ip->i_flag |= IACC|IUPD|ICHG; ! 606: iupdat(ip, &tv[0], &tv[1], 0); ! 607: } ! 608: iput(ip); ! 609: } ! 610: ! 611: /* ! 612: * Setpgrp on specified process and its descendants. ! 613: * Pid of zero implies current process. ! 614: * Pgrp -1 is getpgrp system call returning ! 615: * current process group. ! 616: */ ! 617: setpgrp() ! 618: { ! 619: register struct proc *top; ! 620: register struct a { ! 621: int pid; ! 622: int pgrp; ! 623: } *uap; ! 624: ! 625: uap = (struct a *)u.u_ap; ! 626: uap->pid = (short)uap->pid; /* else 0x10000 would make pgrp 0 */ ! 627: uap->pgrp = (short)uap->pgrp; ! 628: if (uap->pid == 0) ! 629: top = u.u_procp; ! 630: else { ! 631: top = pfind(uap->pid); ! 632: if (top == 0) { ! 633: u.u_error = ESRCH; ! 634: return; ! 635: } ! 636: } ! 637: if (uap->pgrp == 0 && !suser()) ! 638: return; ! 639: ! 640: if (uap->pgrp < 0) { ! 641: u.u_r.r_val1 = top->p_pgrp; ! 642: return; ! 643: } ! 644: if (top->p_uid != u.u_uid && u.u_uid && !inferior(top)) ! 645: u.u_error = EPERM; ! 646: else ! 647: top->p_pgrp = uap->pgrp; ! 648: } ! 649: ! 650: spgrp(top, npgrp) ! 651: register struct proc *top; ! 652: { ! 653: register struct proc *pp, *p; ! 654: int f = 0; ! 655: ! 656: for (p = top; npgrp == -1 || u.u_uid == p->p_uid || ! 657: !u.u_uid || inferior(p); p = pp) { ! 658: if (npgrp == -1) { ! 659: #define bit(a) (1<<(a-1)) ! 660: p->p_sig &= ~(bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); ! 661: } else ! 662: p->p_pgrp = npgrp; ! 663: f++; ! 664: /* ! 665: * Search for children. ! 666: */ ! 667: for (pp = proc; pp < procNPROC; pp++) ! 668: if (pp->p_stat != 0 && pp->p_pptr == p) ! 669: goto cont; ! 670: /* ! 671: * Search for siblings. ! 672: */ ! 673: for (; p != top; p = p->p_pptr) ! 674: for (pp = p + 1; pp < procNPROC; pp++) ! 675: if (pp->p_stat != 0 && pp->p_pptr == p->p_pptr) ! 676: goto cont; ! 677: break; ! 678: cont: ! 679: ; ! 680: } ! 681: return (f); ! 682: } ! 683: ! 684: /* ! 685: * Is p an inferior of the current process? ! 686: */ ! 687: inferior(p) ! 688: register struct proc *p; ! 689: { ! 690: ! 691: for (; p != u.u_procp; p = p->p_pptr) ! 692: if (p < &proc[SYSPIDS]) ! 693: return (0); ! 694: return (1); ! 695: } ! 696: ! 697: sysboot() ! 698: { ! 699: register struct a { ! 700: int opt; ! 701: }; ! 702: ! 703: if (suser()) ! 704: boot(((struct a *)u.u_ap)->opt); ! 705: } ! 706: ! 707: /* ! 708: * lock user into core as much ! 709: * as possible. swapping may still ! 710: * occur if core grows. ! 711: */ ! 712: syslock() ! 713: { ! 714: register struct proc *p; ! 715: register struct a { ! 716: int flag; ! 717: } *uap; ! 718: ! 719: uap = (struct a *)u.u_ap; ! 720: if(suser()) { ! 721: p = u.u_procp; ! 722: p->p_flag &= ~SULOCK; ! 723: if(uap->flag) ! 724: p->p_flag |= SULOCK; ! 725: } ! 726: } ! 727: ! 728: /* ! 729: * nap for n clock ticks ! 730: */ ! 731: #define MAXNAP 120 ! 732: nap() ! 733: { ! 734: register struct a { ! 735: int nticks; ! 736: } *uap; ! 737: register int n; ! 738: ! 739: uap = (struct a *)u.u_ap; ! 740: n = uap->nticks; ! 741: if (n < 0) ! 742: n = 0; ! 743: if (n > MAXNAP) ! 744: n = MAXNAP; ! 745: delay (n); ! 746: } ! 747: ! 748: /* ! 749: * get/set user's login name ! 750: */ ! 751: ! 752: getlogname() ! 753: { ! 754: register struct a { ! 755: char *name; ! 756: int flag; ! 757: } *uap; ! 758: ! 759: uap = (struct a *)u.u_ap; ! 760: if (uap->flag == 0) { ! 761: if (copyout((caddr_t)u.u_logname, (caddr_t)uap->name, sizeof(u.u_logname)) < 0) ! 762: u.u_error = EFAULT; ! 763: return; ! 764: } ! 765: if (suser() == 0) ! 766: return; ! 767: if (copyin((caddr_t)uap->name, (caddr_t)u.u_logname, sizeof(u.u_logname))) ! 768: u.u_error = EFAULT; ! 769: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.