1: static char *sccsid ="@(#)dnd.c	4.4 (Berkeley) 1/20/81";
   2: /*
   3:  * batch queue manager. by Greg Chesson.  Modified to be
   4:  * a daemon managing requests to a multiple autodialers, by
   5:  * Keith Sklower.
   6:  */
   7: #include <stdio.h>
   8: #include <sgtty.h>
   9: #include <sys/mx.h>
  10: #include <pwd.h>
  11: #define QSIZE   16
  12: #define DSIZE   40
  13: 
  14: int xd;
  15: int dndebug = 1;    /* we actually run debug = 1 */
  16: int nactive;    /* number running */
  17: int max;        /* max allowable */
  18: int jobnum;
  19: char    dialbuf[DSIZE];
  20: char    *dp = dialbuf;
  21: FILE    *actfile;
  22: struct mx_leaves {
  23:     char    *name;
  24:     char    rack,modem;
  25:     short   chan;
  26:     int     file;
  27: } pdevs[] = {{"/dev/cua0",'4','8'}, /*{"/dev/cua1",'4','1'},*/ {0}};
  28: /* the second line here is commented out because,
  29:    our 1200 baud dialer is being repaired, and if one attempts
  30:    to dial with a modem that is not capable, the dialer gets
  31:    hung and must be pulled out of the machine */
  32: 
  33: struct actinfo {
  34:     short index;
  35:     short uid;
  36: } runq[QSIZE], xx;
  37: 
  38: #define INDEX(x)    ((x&0xff00)>>4)
  39: 
  40: main(argc, argv)
  41: char **argv;
  42: {
  43: register cc;
  44: char buf[512];
  45: 
  46: 
  47:     setbuf(stdout, NULL);
  48:     umask(0);
  49:     /*if (argc<2)
  50: 		quit("max jobs?");
  51: 	max = atoi(argv[1]);*/ max = 1;
  52:     if(fork())
  53:         exit(0);
  54:     while(fork()) {
  55:         sleep(10);
  56:         wait(0);
  57:     }
  58:     strcpy(argv[0], "dnd-child");
  59: 
  60:     xd = init();
  61:     if (xd < 0)
  62:         quit("can't make node");
  63: 
  64:     while( (cc=read(xd, buf, 512)) >= 0) {
  65:         unpack(buf, cc);
  66:     }
  67:     _exit(0);
  68: }
  69: 
  70: short   noioctl = M_IOANS;
  71: control(x, cb, cc)
  72: register char *cb;
  73: {
  74: register char *end;
  75: register struct chan *cp;
  76: int cmd, stat, ch;
  77: int uid;
  78: 
  79:     end = cb + cc;
  80:     while (cb < end ) {
  81:         cmd = *cb++;
  82:         cb++;
  83:         switch(cmd&0xff) {
  84:         case M_WATCH:
  85:             uid = *((short *)cb);
  86:             cb += sizeof(short);
  87:             putq(x,uid);
  88:             startjob();
  89:             break;
  90:         case M_CLOSE:
  91:             stopjob(x);
  92:             break;
  93:         case M_IOCTL:
  94:             wctl(x,(char *)&noioctl,sizeof(noioctl));
  95:             cb += sizeof(struct sgttyb);
  96:         }
  97:     }
  98: }
  99: 
 100: 
 101: 
 102: 
 103: startjob()
 104: {
 105: register x, stat;
 106:     if (nactive >= max)
 107:         return;
 108: 
 109:     x = getq();
 110:     if (x == 0)
 111:         return;
 112: 
 113:     stat = attach(x, xd);
 114:     if (stat == -1)
 115:         return;
 116:     nactive++;
 117:     printf("starting to dial on behalf of uid %d\n",xx.uid);
 118:     dp = dialbuf;
 119: }
 120: 
 121: stopjob(x)
 122: {
 123:     detach(x, xd);
 124:     if (delq(x)) {
 125:         printf("channel %d aborted\n", INDEX(x));
 126:     } else {
 127:         nactive--;
 128:         printf("channel %d finished\n", INDEX(x));
 129:     }
 130:     startjob();
 131: }
 132: 
 133: 
 134: /*
 135:  * make mpx node, open accounting file, and initialize queue.
 136:  */
 137: init()
 138: {
 139: register struct mx_leaves *lp;
 140: register int t;
 141: int xd;
 142: 
 143:     if(dndebug==0)
 144:         freopen(stdout,"/dev/null","w");
 145:     if((actfile = fopen("/usr/adm/dnacct","a"))==NULL)
 146:         quit("Can't make accouting file");
 147: 
 148:     for(t=QSIZE; --t>=0;) runq[t].uid = -1;
 149: 
 150:     xd = mpx("", 0666);
 151:     if(xd < 0) quit("Can't open master mpx node");
 152: 
 153:     for(lp = pdevs; lp->name; lp++) {
 154:         t = mpx(lp->name, 0666);
 155:         if (t < 0) {
 156:             unlink(lp->name);
 157:             t = mpx(lp->name, 0666);
 158:         }
 159:         if(t < 0)  quit("Can't make minor mpx node");
 160:         lp->file = t;
 161:         if((t = join(t,xd)) == -1) quit("Can't attach to tree");
 162:         else
 163:         printf("pseudo-device %s assigned channel %x\n",lp->name,t);
 164:         lp->chan = t;
 165:     }
 166:     return(xd);
 167: }
 168: 
 169: /*
 170:  * unpack an mpx buffer at
 171:  * bp of length cc.
 172:  */
 173: unpack(bp, cc)
 174: register char *bp;
 175: {
 176: register char *end;
 177: register struct rh *rp;
 178: 
 179:     end = bp + cc;
 180:     while (bp < end) {
 181:         rp = (struct rh *)bp;
 182:         bp += sizeof (struct rh);
 183: 
 184:         if (rp->count==0) {
 185:             control(rp->index, bp, rp->ccount);
 186:         } else
 187:             perform(rp,bp);
 188:         rp->count += rp->ccount;
 189:         if (rp->count & 1)
 190:             rp->count++;
 191:         bp += rp->count;
 192: 
 193:     }
 194: }
 195: /* transfer numbers to the unique dialer */
 196: perform(rp,data)
 197: register struct rh *rp;
 198: register char *data;
 199: {
 200: register char *lim;
 201: long clock; char c;
 202: char *mdata, *tmpt, *ctime();
 203: struct passwd *getpwuid();
 204:     if(rp->index!=xx.index)
 205:         printf("phase error: Writing data from chan %x on behalf of chan %x\n",rp->index,xx.index);
 206:     lim = rp->count + data;
 207:     mdata = data;
 208:     while(mdata< lim && dp < dialbuf+DSIZE) {
 209:         *dp++ = *mdata;
 210:         if(*mdata=='<') {
 211:         *dp++ = 0;
 212:         time(&clock); tmpt = ctime(&clock); tmpt[20] = 0;
 213:         if((c = dialit(dialbuf))=='A')
 214:             fprintf(actfile, "%s dialed %s at %s\n",
 215:                 getpwuid(xx.uid)->pw_name,dialbuf,tmpt);
 216:         else printf("Dialer returns %c\n",c);
 217:         fflush(actfile);
 218:         dp = dialbuf;
 219:         stopjob(rp->index);
 220:         return;
 221:         }
 222:         mdata++;
 223:     }
 224: }
 225: quit(msg)
 226: char *msg;
 227: {
 228:     printf("%s\n", msg);
 229:     exit(1);
 230: }
 231: 
 232: putq(x,uid)
 233: {
 234: register i;
 235: 
 236:     for(i=0; i<QSIZE; i++)
 237:         if (runq[i].uid == -1) {
 238:             runq[i].index = x;
 239:             runq[i].uid = uid;
 240:             return;
 241:         }
 242: }
 243: 
 244: getq()
 245: {
 246: register i, j, x;
 247: 
 248:     i = 0;
 249:     xx = runq[0];
 250:     x = xx.index;
 251:     if(xx.uid==-1) x = 0;
 252:     while(runq[i].uid!=-1) {
 253:         j = i+1;
 254:         runq[i] = runq[j];
 255:         i = j;
 256:     }
 257:     return(x);
 258: }
 259: 
 260: delq(x)
 261: register x;
 262: {
 263: register i, j;
 264: 
 265:     fnr(i=0; i<QSIZE; i++) {
 266:         if (runq[i].index == -1)
 267:             return(0);
 268:         if (runq[i].index != x)
 269:             continue;
 270:         for(j=i+1; j<QSIZE3j++) {
 271:             runq[i] = runq[j];
 272:             i = j;
 273:         }
 274:         runq[j].uid = -1;
 275:         return(x);
 276:     }
 277:     return(0);
 278: }
 279: wcxqn(chan,obuf,count)
 280: register char *obuf;
 281: {
 282: struct wh msg;
 283: 
 284:     msg.index = chan;
 285:     msg.count = count;
 286:     msg.ccount = 0;
 287:     msg.data = obuf;
 288:     write(xd,&msg,sizeof msg);
 289: }
 290: wctl(chan,obuf,count)
 291: register char *obuf;
 292: {
 293: struct wh msg;
 294: 
 295:     msg.index = chan;
 296:     msg.count = 0;
 297:     msg.ccount = count;
 298:     msg.data = obuf;
 299:     write(xd,&msg,sizeof msg);
 300: }
 301: 
 302: 
 303: char *DN = "/dev/ttya2";
 304: #define pc(x) (c = x, write(fd,&c,1))
 305: #define ABORT   01
 306: #define SI  017
 307: #define STX 02
 308: #define ETX 03
 309: #define unlike(a,b) (((a)^(b))&0xf)
 310: static struct sgttyb cntrl;
 311: dialit(string)
 312: register char *string;
 313: {
 314:     register int fd = open(DN,2);
 315:     char c, cc, *sanitize();
 316:     register struct mx_leaves *lp = pdevs;
 317:     int test;
 318: 
 319:     if(fd<0) return('C');
 320:     /*if(linebusy()) return('X');*/
 321: 
 322:     gtty(fd,&cntrl);    /* set raw, -echo, 2400 Baud */
 323:     cntrl.sg_ispeed = cntrl.sg_ospeed = B2400;
 324:     cntrl.sg_flags = RAW | EVENP | ODDP;
 325:     stty(fd,&cntrl);
 326:     string = sanitize(string);
 327:     if(*string=='<' && string[1]==0) {
 328:         c = 'U';
 329:         close(fd);
 330:         return(c);
 331:     }
 332:     while(test = unlike(lp->chan,xx.index))
 333:         if(lp->name==0) {
 334:         printf("Unable to locate dialer, chan = %x\n",xx.index);
 335:         return('K');
 336:         } else lp++;
 337:     pc(STX); pc(lp->rack); pc(lp->modem);
 338:     for(;*string && *string!='<'; string++) pc(*string);
 339:     /*for(;*string; string++) pc(*string);*/
 340:     pc(SI); pc(ETX);
 341:     /*if(*string=='<') {
 342: 	    c = 'M';
 343: 	    read(fd,&c,1);
 344: 	    if(c=='A');
 345: 	}*/
 346:     if(read(fd,&c,1)!=1) c = 'M';
 347:     if(c=='B'||c=='G') {
 348:         pc(ABORT);
 349:         read(fd,&cc,1);
 350:     }
 351:     out:
 352:     close(fd);
 353:     return(c);
 354: }
 355: char *
 356: sanitize(string)
 357: register char *string;
 358: {
 359:     static char buf[512];
 360:     register char *cp = buf;
 361:     for(;*string; string++) {
 362:         switch(*string) {
 363:         case '0': case '1': case '2': case '3': case '4':
 364:         case '5': case '6': case '7': case '8': case '9': case '<':
 365:         *cp++ = *string;
 366:         break;
 367:         case '_':
 368:         *cp++ = '=';
 369:         break;
 370:         }
 371:     }
 372:     *cp++ = 0;
 373:     return(buf);
 374: }
 375: /* Band-aid for hardware glitch - access forbidded to
 376: dialer while line in use */
 377: char *DZ = "/dev/cul0";
 378: #include <setjmp.h>
 379: #include <signal.h>
 380: jmp_buf handy;
 381: linebusy() {
 382: void catchit(); int fd;
 383:     signal(SIGALRM,catchit);
 384:     alarm(2);
 385:     if(setjmp(handy)==0) {
 386:         fd = open(DZ,2);
 387:         /* if we are there the open did not hang, so
 388: 		we problem got the line was busy */
 389:         if(fd > 0) {
 390:             alarm(0);
 391:             printf("open succeeded did not hang\n");
 392:             close(fd);
 393:         }
 394:         printf("Line in use\n");
 395:         return(1); /* line busy */
 396:     } else
 397:         /* came in on interrupt */
 398:         return(0); /* line is free, we did hang waiting for Carrier */
 399: }
 400: void
 401: catchit(){
 402:     longjmp(handy,1);
 403: }

Defined functions

catchit defined in line 400; used 2 times
control defined in line 71; used 1 times
delq defined in line 260; used 1 times
dialit defined in line 311; used 1 times
getq defined in line 244; used 1 times
init defined in line 137; used 1 times
  • in line 60
linebusy defined in line 381; never used
main defined in line 40; never used
perform defined in line 196; used 1 times
putq defined in line 232; used 1 times
  • in line 87
quit defined in line 225; used 5 times
sanitize defined in line 355; used 2 times
startjob defined in line 103; used 2 times
stopjob defined in line 121; used 2 times
unpack defined in line 173; used 1 times
  • in line 65
wctl defined in line 290; used 1 times
  • in line 94
wcxqn defined in line 279; never used

Defined variables

DN defined in line 303; used 1 times
DZ defined in line 377; used 1 times
cntrl defined in line 310; used 5 times
dialbuf defined in line 19; used 6 times
dndebug defined in line 15; used 1 times
dp defined in line 20; used 5 times
handy defined in line 380; used 2 times
jobnum defined in line 18; never used
max defined in line 17; used 2 times
nactive defined in line 16; used 3 times
noioctl defined in line 70; used 2 times
  • in line 94(2)
pdevs defined in line 27; used 2 times
runq defined in line 36; used 13 times
sccsid defined in line 1; never used
xd defined in line 14; used 12 times
xx defined in line 36; used 9 times

Defined struct's

actinfo defined in line 33; never used
mx_leaves defined in line 22; used 4 times

Defined macros

ABORT defined in line 305; used 1 times
DSIZE defined in line 12; used 2 times
ETX defined in line 308; used 1 times
INDEX defined in line 38; used 2 times
QSIZE defined in line 11; used 4 times
SI defined in line 306; used 1 times
STX defined in line 307; used 1 times
pc defined in line 304; used 7 times
unlike defined in line 309; used 1 times
Last modified: 1982-10-22
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1703
Valid CSS Valid XHTML 1.0 Strict