int main(int argc, char **argv) { int sent, received; long mask; int port = 5000; /* default rconsole port */ struct timeval block = { 1, 0}; struct hostent *remotehost; char *host = getenv("AEGIS_HOST"); char line[LINESIZE]; char *buffer = (char *)malloc(BUFSIZE); char sequence = 0; int i; char *word,*nextword; setbuf(stdout,NULL); /* set stdout unbuffered */ /* Open Source Socket */ if (!strcmp(argv[0],"rshutdown")) {shutdown_flag = 1;} for(i = 1; i < argc; i++) { word = argv[i]; nextword = (i+1 >= argc) ? 0 : argv[i+1]; if (!strcmp(word,"-shutdown")) { shutdown_flag = 1; } else if (!strcmp(word,"-help") || !strcmp(word,"--help")) { print_usage(); } else if (!strcmp(word,"-off")) { off_flag = 1; } else if (!strcmp(word,"-noseq")) { seq_flag = 0; } else if (!strcmp(word,"-log")) { if (!nextword) print_usage(); log_flag = 1; if ((logfile = open(nextword,O_APPEND|O_WRONLY|O_CREAT,0664)) == 0) { printf("could not open: %s\n",nextword); exit(-1); } i++; } else { host = word; if (nextword) { port = atoi(nextword); i++; } } } if ((sockfd=socket(PF_INET,SOCK_DGRAM,0)) < 0) printf("Client can't open datagram socket\n"); memset((char *) &cli_addr,0,sizeof(cli_addr)); cli_addr.sin_family = AF_INET; if (bind(sockfd,(struct sockaddr *) &cli_addr,sizeof(cli_addr)) < 0) {printf("Unable to bind"); return -1;} memset((char *) &serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; remotehost = gethostbyname(host); if (remotehost == 0) {printf ("Unknown host: %s\n",host); exit(1);} memcpy( (char *) &serv_addr.sin_addr,remotehost->h_addr, remotehost->h_length); serv_addr.sin_port = htons(port); printf("Using host: %s port: %d\n",host,port); do { mask = 1 << sockfd; /* nice way for selecting on one socket! */ if (shutdown_flag) { printf("sending shutdown commmand...\n"); sent = sendto(sockfd, "\001", 1, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); } else if (off_flag) { printf("sending off daemon commmand...\n"); sent = sendto(sockfd, "\002", 1, 0,(struct sockaddr *)&serv_addr, sizeof(serv_addr)); } else { char *user; int length; #if 0 user = getenv("USER"); length = strlen(user) + 1; #else user = setupenv(&length); #endif sent = sendto(sockfd, user, length, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); } select(32,(fd_set *)&mask,0,0,&block); } while(!mask); received = recvfrom(sockfd,buffer,4,0,&dummy_addr,&dummy_len); if (*((int *)buffer) == 0) {printf("done\n");exit(0);} do { unsigned short port; memcpy(&port,buffer,2); printf("rconsole version %s, rconsolec moving to port: %d\n", RCONSOLE_VERSION,htons(port)); serv_addr.sin_port = port; } while(0); if ((child_pid = fork())) { signal(SIGINT,controlc); signal(SIGTERM,controlc); signal(SIGCHLD,SIG_IGN); signal(SIGALRM,timeout_handler); alarm(TIMEOUT*3600); /* parent */ printf("Child pid: %d\n",child_pid); while(1) { int length; char *ret; memset(&line[0],0,LINESIZE); ret = fgets(line,LINESIZE,stdin); /* printf("line: \"%s\"\n",line); */ length = strlen(line) + 1; if (line[length-1] == '\n') {line[length-1] = 0; length--;} if (ret == NULL) { printf("Type Control-C to quit\n\n"); close(0); while(1) {sleep(1000);} } if (!strcmp(line,"clear")) {system("clear"); sent = sendto(sockfd, "\n", 2, 0, (struct sockaddr *)&serv_addr, sizeof(serv_addr)); /* so that the prompt moves */ continue;} /* replace NULL char by newline (gets does not retain the newline) */ line[length - 1] = '\n'; line[length] = 0; #if 0 printf("send line:\n*"); for (i = 0; i < length; i++) { putchar(line[i]); } printf("* (length: %d)\n",length); #endif /* sleep(1); */ sent = sendto(sockfd, line, length, 0,(struct sockaddr *)&serv_addr, sizeof(serv_addr)); if (log_flag) {write(logfile,line,length);} /* put back the NULL so that strncmp works safely */ line[length - 1] = (char )NULL; if (!strcmp(line,"logout")) break; if (!strcmp(line,"shutdown")) {sleep(1);break;} } controlc(); } else { signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN); close(0); while(1) { /* Receiving loop */ received = recvfrom(sockfd,buffer,BUFSIZE,0,&dummy_addr,&dummy_len); if (sequence != buffer[0] && seq_flag) { printf("* Received a packet out of sequence.\n"); sequence = buffer[0]; } sequence = (sequence + 1) & 0xFF; write(1,(char *)buffer + seq_flag,received-seq_flag); /* for (i = 0; i < received ; i++) putchar(buffer[i]); */ if (log_flag) { write(logfile,(char *)buffer + seq_flag,received-1); } } } return(0); }
void timeout_handler() { printf("%d hours have passed since the rconsole.ng started... timing out\n",TIMEOUT); controlc(); }
//**************************************************************************** // Attach to an environment - switches are: // x = xecute command Opt // e = environment (UCI) Opt int INIT_Run( char *file, // database file char *env, // environment (UCI) char *cmd) // command { int i; // an int int dbfd = 0; // database file descriptor int ret = 0; // return value int env_num = 1; // startup environemnt number var_u tmp; // temp descriptor uci_tab *uci_ptr; // for uci search int pid; // job number int ssp = 0; // string stack ptr int asp = 0; // address stack ptr mvar *var; // a variable pointer cstring *cptr; // a handy pointer cstring *sptr; // cstring ptr short s; // for functions short start_type = TYPE_RUN; // how we started gid_t gidset[MAX_GROUPS]; // for getgroups() struct termios tty_settings; // man 4 termios start: #if defined(__APPLE__) || defined(__FreeBSD__) srandomdev(); // randomize #endif partab.jobtab = (jobtab *) NULL; // clear jobtab pointer dbfd = open(file, O_RDONLY); // open the database for read if (dbfd < 0) return (errno); // if that failed // i = fcntl(dbfd, F_NOCACHE, 1); if (start_type == TYPE_RUN) // if not from JOB { i = UTIL_Share(file); // attach to shared mem if (i != 0) return(i); // quit on error } if (env != NULL) // passed in uci ? { env_num = 0; // clear uci number uci_ptr = &systab->vol[0]->vollab->uci[0]; // get ptr to uci table //tmp.var_qu = 0; // zero entire name X_Clear(tmp.var_xu); // zero entire name for (i = 0; i < MAX_NAME_BYTES; i++) // copy in name { if (env[i] == '\0') break; // done at null tmp.var_cu[i] = env[i]; // copy character } for (i = 0; i < UCIS; i++) // scan all ucis //if (uci_ptr[i].name.var_qu == tmp.var_qu) // if we have a match if (X_EQ(uci_ptr[i].name.var_xu, tmp.var_xu)) // if we have a match { env_num = i + 1; // save it break; // and exit loop } if (env_num == 0) { ret = ENOENT; // complain on fail goto exit; // and exit } } pid = (int) getpid(); // get process id for (i = 0; i < systab->maxjob; i++) // scan the slots { ret = systab->jobtab[i].pid; // get pid if ((ret != pid) && (ret)) // if one there and not us { if (kill(ret, 0)) // check the job { if (errno == ESRCH) // doesn't exist { ret = CleanJob(i + 1); // zot if not there if (ret == 0) // success ? break; // have at least one } } } else // it's free or ours { break; // quit } } ret = SemOp(SEM_SYS, -systab->maxjob); // lock systab if (ret < 0) goto exit; // give up on error for (i = 0; i < systab->maxjob; i++) // look for a free slot { if (((systab->jobtab[i].pid == 0) && // this one ? (start_type == TYPE_RUN)) || ((systab->jobtab[i].pid == pid) && // or already done (JOB) (start_type == TYPE_JOB))) { bzero(&systab->jobtab[i], sizeof(jobtab)); // yes - zot the lot partab.jobtab = &systab->jobtab[i]; // and save our jobtab address partab.jobtab->pid = pid; // copy in our pid break; // end loop } } ret = SemOp(SEM_SYS, systab->maxjob); // unlock systab if (partab.jobtab == NULL) // if that failed { ret = ENOMEM; // error message goto exit; // and exit } partab.jobtab->user = (short) getuid(); // get user number if ((partab.jobtab->user == systab->start_user) || // if he started it (partab.jobtab->user == 0)) // or is root { partab.jobtab->priv = 1; // say yes } else { if (systab->maxjob == 1) // if single job { ret = ENOMEM; // error message partab.jobtab = NULL; // clear this goto exit; // and exit } i = getgroups(MAX_GROUPS, gidset); // get groups if (i < 0) // if an error { ret = errno; // get the error goto exit; // and exit } while (i > 0) // for each group { if (gidset[i - 1] == PRVGRP) // if it's "wheel" or "admin" { partab.jobtab->priv = 1; // say yes break; // and exit } i--; // decrement i } } partab.jobtab->precision = systab->precision; // decimal precision partab.jobtab->uci = env_num; // uci number partab.jobtab->vol = 1; // volset partab.jobtab->luci = env_num; // uci number partab.jobtab->lvol = 1; // volset partab.jobtab->ruci = env_num; // uci number partab.jobtab->rvol = 1; // volset partab.jobtab->start_len = Vhorolog(partab.jobtab->start_dh); // store start date/time partab.jobtab->dostk[0].type = TYPE_RUN; // ensure slot 0 has a value failed_tty = tcgetattr ( 0, &tty_settings ); i = SQ_Init(); // have seqio setup chan 0 systab->last_blk_used[partab.jobtab - systab->jobtab] = 0; // clear last global block partab.debug = 0; // clear debug flag partab.sstk_start = &sstk[0]; // address of sstk partab.sstk_last = &sstk[MAX_SSTK]; // and the last char partab.varlst = NULL; // used by compiler partab.vol_fds[0] = dbfd; // make sure fd is right ST_Init(); // initialize symbol table if ((systab->vol[0]->vollab->journal_available) && (systab->vol[0]->vollab->journal_requested)) // if journaling { partab.jnl_fds[0] = open(systab->vol[0]->vollab->journal_file, O_RDWR); if (partab.jnl_fds[0] < 0) { fprintf(stderr, "Failed to open journal file %s\nerrno = %d\n", systab->vol[0]->vollab->journal_file, errno); ret = -1; if (cmd != NULL) goto exit; } else { // i = fcntl(dbfd, F_NOCACHE, 1); } } if (cmd != NULL) // command specified ? { source_ptr = (u_char *) cmd; // where the code is cptr = (cstring *) &sstk[ssp]; // where the compiled goes comp_ptr = cptr->buf; // the data bit parse(); *comp_ptr++ = CMQUIT; // add the quit *comp_ptr++ = ENDLIN; // JIC *comp_ptr++ = ENDLIN; // JIC i = &comp_ptr[0] - &cptr->buf[0]; // get number of bytes cptr->len = i; // save for ron ssp = ssp + i + sizeof(short) + 1; // point past it mumpspc = &cptr->buf[0]; // setup the mumpspc partab.jobtab->dostk[0].routine = (u_char *) cmd; // where we started partab.jobtab->dostk[0].pc = mumpspc; // where we started partab.jobtab->dostk[0].symbol = NULL; // nowhere partab.jobtab->dostk[0].newtab = NULL; // nowhere partab.jobtab->dostk[0].endlin = mumpspc + i - 4; // ENDLIN //partab.jobtab->dostk[0].rounam.var_qu = 0;// zero the routine name X_Clear(partab.jobtab->dostk[0].rounam.var_xu); // zero the routine name partab.jobtab->dostk[0].vol = partab.jobtab->vol; // current volume partab.jobtab->dostk[0].uci = partab.jobtab->uci; // current uci partab.jobtab->dostk[0].line_num = 0; // no line number partab.jobtab->dostk[0].type = start_type; // how we started partab.jobtab->dostk[0].estack = 0; // estack offset partab.jobtab->dostk[0].level = 0; // where we started partab.jobtab->dostk[0].flags = 0; // no flags partab.jobtab->dostk[0].savasp = asp; // address stack ptr partab.jobtab->dostk[0].savssp = ssp; // string stack partab.jobtab->dostk[0].asp = asp; // address stack ptr partab.jobtab->dostk[0].ssp = ssp; // string stack partab.jobtab->attention = 0; partab.jobtab->trap = 0; partab.jobtab->async_error = 0; isp = 0; // clear indirect pointer s = run(asp, ssp); if (s == OPHALT) goto exit; // look after halt if (s == JOBIT) goto jobit; // look after JOB partab.jobtab->io = 0; // force chan 0 var = (mvar *) &sstk[0]; // space to setup a var X_set("$ECODE\0\0", &var->name.var_cu[0], 8); var->volset = 0; var->uci = UCI_IS_LOCALVAR; var->slen = 0; // setup for $EC cptr = (cstring *) &sstk[sizeof(mvar)]; // for result bcopy("$ECODE=", cptr->buf, 7); s = ST_Get(var, &cptr->buf[7]); if (s > 1) // ignore if nothing there { cptr->len = s + 7; s = SQ_WriteFormat(SQ_LF); // new line s = SQ_Write(cptr); // write the prompt s = SQ_WriteFormat(SQ_LF); // new line cptr = (cstring *) (((u_char *) cptr) + 8); if (cptr->buf[0] != 'U') { cptr->len = 4; // max error size cptr->len = Xcall_errmsg((char *) cptr->buf, cptr, cptr); // cvt to str s = SQ_Write(cptr); // write the error s = SQ_WriteFormat(SQ_LF); // new line } ret = ESRCH; // set an error for exit } goto exit; // and halt } while (TRUE) // forever { sptr = (cstring *) &sstk[0]; // front of string stack asp = 0; // zot address stack ssp = 0; // and the string stack bcopy("M> ", sptr->buf, 3); // copy in the prompt sptr->buf[3] = '\0'; // null terminate sptr->len = 3; // and the length partab.jobtab->io = 0; // force chan 0 if (partab.jobtab->seqio[0].dx) // if not at right margin { s = SQ_WriteFormat(SQ_LF); // new line if (s < 0) ser(s); // check for error } s = SQ_Write(sptr); // write the prompt if (s < 0) ser(s); // check for error s = SQ_Read(sptr->buf, -1, -1); // get a string i = attention(); // check signals if (i == OPHALT) break; // exit on halt if (i == -(ERRZ51+ERRMLAST)) // control c controlc(); // say if (s < 0) { ser(s); // complain on error s = 0; } sptr->len = s; // save the length if (s == 0) continue; // ignore null astk[asp++] = (u_char *) sptr; // save address of string ssp = ssp + s + sizeof(short) + 1; // point past it s = SQ_WriteFormat(SQ_LF); // new line if (s < 0) ser(s); // check for error source_ptr = sptr->buf; // where the code is cptr = (cstring *) &sstk[ssp]; // where the compiled goes comp_ptr = cptr->buf; // the data bit parse(); *comp_ptr++ = CMQUIT; // add the quit *comp_ptr++ = ENDLIN; // JIC *comp_ptr++ = ENDLIN; // JIC i = &comp_ptr[0] - &cptr->buf[0]; // get number of bytes cptr->len = i; // save for ron ssp = ssp + i + sizeof(short) + 1; // point past it mumpspc = &cptr->buf[0]; // setup the mumpspc partab.jobtab->dostk[0].routine = sptr->buf; // where we started partab.jobtab->dostk[0].pc = mumpspc; // where we started partab.jobtab->dostk[0].symbol = NULL; // nowhere partab.jobtab->dostk[0].newtab = NULL; // nowhere partab.jobtab->dostk[0].endlin = mumpspc + i - 4; // ENDLIN //partab.jobtab->dostk[0].rounam.var_qu = 0;// zero the routine name X_Clear(partab.jobtab->dostk[0].rounam.var_xu);// zero the routine name partab.jobtab->dostk[0].vol = partab.jobtab->vol; // current volume partab.jobtab->dostk[0].uci = partab.jobtab->uci; // current uci partab.jobtab->dostk[0].line_num = 0; // no line number partab.jobtab->dostk[0].type = TYPE_RUN; // how we started partab.jobtab->dostk[0].estack = 0; // estack offset partab.jobtab->dostk[0].level = 0; // where we started partab.jobtab->dostk[0].flags = 0; // no flags partab.jobtab->dostk[0].savasp = asp; // address stack ptr partab.jobtab->dostk[0].savssp = ssp; // string stack partab.jobtab->dostk[0].asp = asp; // address stack ptr partab.jobtab->dostk[0].ssp = ssp; // string stack partab.jobtab->attention = 0; partab.jobtab->trap = 0; partab.jobtab->async_error = 0; isp = 0; // clear indirect pointer s = run(asp, ssp); if (s == JOBIT) goto jobit; // look after JOB if (s == OPHALT) break; // exit on halt partab.jobtab->io = 0; // force chan 0 if (s == -(ERRZ51+ERRMLAST)) // control c controlc(); // say else if (s < 0) ser(s); partab.jobtab->error_frame = 0; // and that one var = (mvar *) &sstk[0]; // space to setup a var X_set("$ECODE\0\0", &var->name.var_cu[0], 8); var->volset = 0; var->uci = UCI_IS_LOCALVAR; var->slen = 0; // setup for $EC cptr = (cstring *) &sstk[sizeof(mvar)]; // for result bcopy("$ECODE=", cptr->buf, 7); s = ST_Get(var, &cptr->buf[7]); if (s < 1) continue; // ignore if nothing there cptr->len = s + 7; s = SQ_Write(cptr); // write the prompt if (s < 0) ser(s); // check for error s = SQ_WriteFormat(SQ_LF); // new line if (s < 0) ser(s); // check for error s = ST_Kill(var); // dong $EC cptr = (cstring *) (((u_char *) cptr) + 8); if (cptr->buf[0] != 'U') { cptr->len = 4; // max error size cptr->len = Xcall_errmsg((char *) cptr->buf, cptr, cptr); // cvt to str s = SQ_Write(cptr); // write the error if (s < 0) ser(s); // check for error s = SQ_WriteFormat(SQ_LF); // new line } } // end command level loop exit: // general exit code if (partab.jobtab != NULL) // if we have a jobtab CleanJob(0); // remove all locks etc i = shmdt(systab); // detach the shared mem if (dbfd) i = close(dbfd); // close the database if (!failed_tty) // reset terminal if possible { failed_tty = tcsetattr ( 0, TCSANOW, &tty_settings ); } if (start_type == TYPE_JOB) return 0; // no error from JOB return ret; // and exit jobit: // code for JOB start_type = TYPE_JOB; // what we are doing env_num = partab.jobtab->ruci; // remember (current) rou uci cmd = (char *) &sstk[0]; // where the command is ssp = strlen((const char *) sstk); // protect original command isp = 0; // clear all these asp = 0; ret = 0; env = NULL; goto start; // go do it }