|
|
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.