Beispiel #1
0
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);
}
Beispiel #2
0
void timeout_handler() {
    printf("%d hours have passed since the rconsole.ng started... timing out\n",TIMEOUT);
    controlc();
}
Beispiel #3
0
//****************************************************************************
// 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
}