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