/* Kermit's privileged services. These services include the setting of the baudrate of a port, and the retrieval of the number of free blocks on the specified device. This is done by means of a privileged server task, which does the dirty work. We talk to this task with two pipes. */ #include "ufk.h" prv_init() { int pid, in, out, p; char c, *prm[2]; static char *tname = { "kermit_support" }; if (prvsetdone) /* If setup already done... */ return; /* then get the hell out of here */ in = 0; out = 1; prm[0] = tname; prm[1] = 0; if ((pipe(pd1) == ERROR) || /* Create input pipe */ (pipe(pd2) == ERROR) || /* Create output pipe */ ((pid = fork()) == ERROR)) /* Create child process */ { prterr(ER_PRIVSERVER); /* Something wrong */ kerm_exit(); } if (!pid) { /* child process */ close(pd1[READ]); /* Close one side for read */ close(pd2[WRITE]); /* and the other side for write */ dup2(pd2[READ],in); /* Copy to stdin */ dup2(pd1[WRITE],out); /* and to stdout */ for (c=2; c < 10; c++) close(c); /* close all files */ execv(PRIVTASK,prm); /* Try to start the support task */ c = 0; /* Too bad if we come here */ write(out,&c,1); /* Send error to parent */ exit(1); /* Error exit for child */ } close(pd1[WRITE]); /* Close one side for write */ close(pd2[READ]); /* and the other side for read */ pread(&c,1); /* Get acknowledge from server or child */ if (c == 0) /* If false then the support task */ { /* did not run */ prterr(ER_PRIVSERVER); /* Something wrong */ kerm_exit(); } prvsetdone = TRUE; /* setup ok */ if (c < PROTOCOL_VERSION) /* Check for correct protocol */ { prterr(ER_PRIVPROT); /* Invalid protocol */ kerm_exit(); } } baud(dev,rate) char *dev; int rate; { int len, stat; prv_init(); /* Do the necessary setup */ len = strlen(dev) + 1; /* must send terminator as well */ pwrite("b",1); /* 'baudrate' command */ pwrite(&len,2); /* length of device name */ pwrite(dev,len); /* device name */ pwrite(&rate,2); /* baudrate */ pwrite(&maskflag,1); /* mask flag for RTS & DCD */ pread(&stat,2); /* read status */ if (stat) { sup_error(); /* get and print support task error */ return TRUE; } return FALSE; } do_break(dev) char *dev; { int len, stat; prv_init(); /* Do the necessary setup */ len = strlen(dev) + 1; /* must send terminator as well */ pwrite("w",1); /* 'break' command */ pwrite(&len,2); /* length of device name */ pwrite(dev,len); /* device name */ pread(&stat,2); /* read status */ if (stat) { sup_error(); /* get and print support task error */ return TRUE; } return FALSE; } fset_date(file,date) char *file; long date; { int len, stat; prv_init(); /* Do the necessary setup */ len = strlen(file) + 1; /* must send terminator as well */ pwrite("d",1); /* 'date' command */ pwrite(&len,2); /* length of file name */ pwrite(file,len); /* file name */ pwrite(&date,4); /* date */ pread(&stat,2); /* read status */ if (stat) { sup_error(); /* get and print support task error */ return TRUE; } return FALSE; } set_dir(dir) char *dir; { int len, stat; prv_init(); /* Do the necessary setup */ len = strlen(dir) + 1; /* must send terminator as well */ pwrite("s",1); /* 'date' command */ pwrite(&len,2); /* length of file name */ pwrite(dir,len); /* file name */ pread(&stat,2); /* read status */ if (stat) { sup_error(); /* get and print support task error */ return TRUE; } return FALSE; } long get_free(dev) char *dev; { int len; long size; prv_init(); /* Do the necessary setup */ len = strlen(dev) + 1; /* must send terminator as well */ pwrite("f",1); /* 'free blocks' command */ pwrite(&len,2); /* device name length */ pwrite(dev,len); /* device name itself */ pread(&size,4); /* Get size */ if (size == -1l) /* error ? */ sup_error(); /* get and print support task error */ return size; } sup_exit() { if (prvsetdone) /* If setup done... */ pwrite("e",1); /* 'exit' command */ } sup_error() { int len; char data[100]; pread(&len,2); /* get length of error string */ pread(data,len); /* get error string */ fprintf(stderr,"%s\n",data); }