|
|
1.1 root 1: /*
2: * reboot stream module and device
3: */
4:
5: #include "u.h"
6: #include "../port/lib.h"
7: #include "mem.h"
8: #include "dat.h"
9: #include "fns.h"
10: #include "../port/error.h"
11:
12: #include "devtab.h"
13:
14: enum{
15: Dirqid,
16: Deltatqid,
17: Zotqid,
18: };
19:
20: Dirtab Reboottab[]={
21: "deltat", {Deltatqid, 0}, NUMSIZE, 0660,
22: "zot", {Zotqid, 0}, 0, 0220,
23: };
24:
25: #define NReboottab (sizeof(Reboottab)/sizeof(Dirtab))
26:
27: /*
28: * stream module definition
29: */
30: static void rebootstopen(Queue*, Stream*);
31: static void rebootiput(Queue*, Block*);
32: static void rebootoput(Queue*, Block*);
33: static Qinfo rebootinfo =
34: {
35: rebootiput,
36: rebootoput,
37: rebootstopen,
38: 0,
39: "reboot",
40: 0
41: };
42:
43: static Rendez timer;
44: static int deltat;
45:
46: void
47: rebootreset(void)
48: {
49: newqinfo(&rebootinfo);
50: }
51:
52: void
53: rebootinit(void)
54: {
55: }
56:
57: Chan *
58: rebootattach(char *spec)
59: {
60: return devattach(L'↑', spec);
61: }
62:
63: Chan *
64: rebootclone(Chan *c, Chan *nc)
65: {
66: return devclone(c, nc);
67: }
68:
69: int
70: rebootwalk(Chan *c, char *name)
71: {
72: return devwalk(c, name, Reboottab, NReboottab, devgen);
73: }
74:
75: void
76: rebootstat(Chan *c, char *db)
77: {
78: devstat(c, db, Reboottab, NReboottab, devgen);
79: }
80:
81: Chan *
82: rebootopen(Chan *c, int omode)
83: {
84: return devopen(c, omode, Reboottab, NReboottab, devgen);
85: }
86:
87: void
88: rebootcreate(Chan *c, char *name, int omode, ulong perm)
89: {
90: USED(c, name, omode, perm);
91: error(Eperm);
92: }
93:
94: void
95: rebootremove(Chan *c)
96: {
97: USED(c);
98: error(Eperm);
99: }
100:
101: void
102: rebootwstat(Chan *c, char *dp)
103: {
104: USED(c, dp);
105: error(Eperm);
106: }
107:
108: void
109: rebootclose(Chan *c)
110: {
111: USED(c);
112: }
113:
114: long
115: rebootread(Chan *c, void *a, long n, ulong offset)
116: {
117: switch(c->qid.path & ~CHDIR){
118: case Dirqid:
119: return devdirread(c, a, n, Reboottab, NReboottab, devgen);
120: case Deltatqid:
121: return readnum(offset, a, n, deltat, NUMSIZE);
122: default:
123: n=0;
124: break;
125: }
126: return n;
127: }
128:
129: long
130: rebootwrite(Chan *c, char *a, long n, ulong offset)
131: {
132: char buf[NUMSIZE];
133: Block *bp;
134:
135: USED(offset);
136: switch(c->qid.path & ~CHDIR){
137: case Deltatqid:
138: if(n > NUMSIZE-1)
139: n = NUMSIZE-1;
140: memmove(buf, a, n);
141: buf[n] = 0;
142: deltat = strtoul(buf, 0, 0);
143: break;
144: case Zotqid:
145: bp = allocb(0);
146: bp->type = M_HANGUP;
147: rebootiput(0, bp);
148: break;
149: default:
150: error(Ebadusefd);
151: }
152: return n;
153: }
154:
155: /*
156: * stream routines
157: */
158:
159: static void
160: rebootstopen(Queue *q, Stream *s)
161: {
162: USED(q, s);
163: if(strcmp(u->p->user, eve) != 0)
164: error(Eperm);
165: }
166:
167: void
168: rebootoput(Queue *q, Block *bp)
169: {
170: PUTNEXT(q, bp);
171: }
172:
173: static void
174: rebootiput(Queue *q, Block *bp)
175: {
176: if(bp->type == M_HANGUP){
177: tsleep(&timer, return0, 0, deltat);
178: exit(0);
179: }
180: PUTNEXT(q, bp);
181: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.