Exemple #1
0
void empire_output(DESC *d, int code, char *buf)
{
  switch (code) {
    case C_NOECHO:
      break;	/* maybe do something later */
    case C_FLUSH:
      process_output(d);
      break;
    case C_ABORT:
      queue_string(d,"Aborted\r\n");
      break;
    case C_CMDERR:
    case C_BADCMD:
      queue_string(d,"Error; ");
      break;
    case C_EXIT:
      queue_string(d,"Exit: ");
      break;
    case C_FLASH:
      queue_string(d,"\r\n");
      break;
    default:
      break;
  }
  queue_string(d, buf);
  if (code != C_FLUSH)
    queue_string(d,"\r\n");
  else
    process_output(d);
}
Exemple #2
0
int enq_output(uart_ctx_t* ctx, dthread_t* self,
	       dmessage_t* mp, ErlDrvTermData from)
{
    dmessage_t* mr;

    mp->next = NULL;
    mp->from = from;  // from = 0 => async

    // set packet bytes header!
    set_packet_bytes(mp, ctx->option.htype);

    if ((ctx->oq.mesg == NULL) && (ctx->oq.front == NULL)) {
	ctx->oq.offs = 0;
	ctx->oq.mesg = mp;
	return process_output(ctx, self);
    }
    else {
	if ((mr = ctx->oq.rear) != NULL)
	    mr->next = mp;
	else
	    ctx->oq.front = mp;
	ctx->oq.rear = mp;
	return 0;
    }
}
Exemple #3
0
void            tell_player(player * p, char *str)
{
   file            output;
   char           *oldstack, *script;
   oldstack = stack;
   if (((p->fd) < 0) || (p->flags & PANIC))
      return;
   if (!(sys_flags & PANIC))
      if (!test_receive(p))
	 return;
   output = process_output(p, str);
   if (p->script)
   {
      script = stack;
      sprintf(stack, "emergency/%s_emergency", p->lower_name);
      stack = end_string(stack);
      log(script, str);
      stack = script;
   }
   if (write(0, output.where, output.length) < 0)
   {
      p->flags |= PANIC;
      log("error", "PANIC trying to write to player.");
   }
   stack = oldstack;
}
Exemple #4
0
void ProcessQueue::run_command( const ProcessCommand& cmd )
{
	emit process_output(QString("\n-------------------------------------------"
		"\n-------------------------------------------"
		"\n-------------------------------------------\nExecuting: ") + cmd.commandLine + QString("\n\n"));
	run_redirected_process(cmd.commandLine.toAscii().data(), boost::bind(&ProcessQueue::process_output_callback, this, boost::ref(cmd), _1, _2));
}
Exemple #5
0
int
file_prober_c::run(const QString &input_file_name) {
  m_file->m_name = input_file_name;

  if (!m_options_file->open()) {
    QMessageBox::critical(m_parent, Q(Y("Error querying mkvmerge")),
                          Q(Y("The file cannot be used because mmg could not create a temporary file (reason: %1).")).arg(m_options_file->errorString()));
    return -1;
  }

  static const unsigned char utf8_bom[3] = {0xef, 0xbb, 0xbf};
  m_options_file->write((const char *)utf8_bom, 3);
  m_options_file->write(QByteArray("--output-charset\nUTF-8\n--identify-for-mmg\n"));
  m_options_file->write(input_file_name.toUtf8());
  m_options_file->write(QByteArray("\n"));
  m_options_file->flush();

  QStringList args;
  args << Q("@%1").arg(m_options_file->fileName());
  m_process.start(m_parent->get_mkvmerge_settings().executable, args);

  while (!m_process.waitForFinished(10)) {
    qApp->processEvents();
    qApp->sendPostedEvents();
  }

  return process_output();
}
void
server_loop2(Authctxt *authctxt)
{
	fd_set *readset = NULL, *writeset = NULL;
	int rekeying = 0, max_fd, nalloc = 0;

	debug("Entering interactive session for SSH2.");

	mysignal(SIGCHLD, sigchld_handler);
	child_terminated = 0;
	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	notify_setup();

	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, notify_pipe[0]);

	xxx_authctxt = authctxt;

	server_init_dispatch();

	for (;;) {
		process_buffered_input_packets();

		rekeying = (xxx_kex != NULL && !xxx_kex->done);

		if (!rekeying && packet_not_very_much_data_to_write())
			channel_output_poll();
		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, 0);

		collect_children();
		if (!rekeying) {
			channel_after_select(readset, writeset);
			if (packet_need_rekeying()) {
				debug("need rekeying");
				xxx_kex->done = 0;
				kex_send_kexinit(xxx_kex);
			}
		}
		process_input(readset);
		if (connection_closed)
			break;
		process_output(writeset);
	}
	collect_children();

	if (readset)
		xfree(readset);
	if (writeset)
		xfree(writeset);

	/* free all channels, no more reads and writes */
	channel_free_all();

	/* free remaining sessions, e.g. remove wtmp entries */
	session_destroy_all(NULL);
}
Exemple #7
0
int main()
{
    simplerUpgrade();
    process_simple_output();
    process_output();
    view_output();
    return 0;
}
Exemple #8
0
void empire_prompt(DESC *d)
{
  char buf[1024];

  if (d->door_int1 == C_PROMPT)
    queue_string(d,"\r\n");
  sprintf(buf,"%s%s\r\n",d->door_mbuf,d->door_lbuf);
  queue_string(d,buf);
  process_output(d);
}
void close_socket( link_data* link, bool process )
{
  char              buf [ MAX_STRING_LENGTH ];
  char_data*         ch;
  int         connected  = link->connected;

  if( link->channel == -1 ) {
    bug( "Close_Socket: Closing a dead socket??" );
    return;
    }

  // unswitch
  if( ( ch = link->player ) != NULL && ch != link->character )
    do_return( link->character, "" );

  // send last of buffer
  if( process ) {
    link->connected = CON_CLOSING_LINK;
    process_output( link );
    }

  // send EOF
  send(link->channel, empty_string, 1, (unsigned int) 0);

  if( ch != NULL ) {
    if( connected == CON_PLAYING ) {
      send_seen( ch, "%s has lost %s link.\n\r",
        ch, ch->His_Her( ) );
      sprintf( buf, "%s has lost link.", ch->descr->name );
      info( buf, LEVEL_IMMORTAL, buf, IFLAG_LOGINS, 1, ch );
      ch->link = NULL;
      }
    else {
      if( ch->shdata->level == 0 && ch->pcdata->pfile != NULL ) 
        extract( ch->pcdata->pfile, link );
      ch->Extract( );
      }  
    }

  close( link->channel );
  extract( link );

  return;
}
Exemple #10
0
Fichier : s.c Projet : TAEB/bridey
void handle_msg() {
   switch (msg.type) {
   case END:
      done++;
      break;;
   case TEST:
      msg.buf[msg.len] = '\0';
      printf("Testing won too thee. Got: %s\n", msg.buf);
      break;
   case OUTPUT:
      if (big_format)
         process_output(msg.buf, msg.len);
      else
         write(1, msg.buf, msg.len);
      break;
   case PAUSED:
      write(fd, paused ? "#t " : "#f ", 3);
      paused = 0;
      break;
   }
}
Exemple #11
0
int main_loop(int client_socket, int motors_socket)
{
	char msg_buf[BUFSIZ];
	float phi, xleft, xright;
	int rc;

	while (1) {
		memset(msg_buf, 0, BUFSIZ);
		rc = recv(client_socket, msg_buf, BUFSIZ, 0);
		if (rc < 0) {
			fprintf(stderr, "recv returned exit status %d\n", errno);
			goto error;
		}
		if (rc == 0) {
			close(client_socket);
			break;
		}
		rc = parse_msg(msg_buf, &phi, &xleft, &xright);
		if (rc < 0) {
			fprintf(stderr, "parse_msg returned exit code %d\n", rc);
			continue;
		}
#if 0
		fuzzy(phi, xleft, xright);
#endif
		process_output(msg_buf, phi, xleft, xright);
		rc = send(motors_socket, msg_buf, strlen(msg_buf), 0);
		if (rc < 0) {
			fprintf(stderr, "send() returned exit status %d\n", errno);
			goto error;
		}
	}
	return 0;
error:
	return -errno;
}
/*----------------------------------------------------------------------*/
int main(int argc, char **argv)
{
	/* MBIO status variables */
	int status = MB_SUCCESS;
	int error = MB_ERROR_NO_ERROR;

	/* MBIO read control parameters */
	int read_datalist = MB_NO;
	void *datalist;
	int look_processed = MB_DATALIST_LOOK_UNSET;
	double file_weight;
	mb_path ifile;

	/* MBIO read values */
	int read_data;

	/* counting variables */
	counts filerecs;
	counts totrecs;

	/* processing variables */
	options opts;
	mbdefaults mbdflts;

	/* set default options */
	default_options(&opts);

	/* mb_mem_debug_on(opts.verbose, &error); */

	/* get mbsystem default values */
	status = mb_defaults(opts.verbose, &(mbdflts.format), &(mbdflts.pings_get),
		&(mbdflts.lonflip), mbdflts.bounds, mbdflts.btime_i,
		mbdflts.etime_i, &(mbdflts.speedmin),
		&(mbdflts.timegap));

	if (status == MB_SUCCESS)
		{
		parse_options(opts.verbose, argc, argv, &opts, &error);
		}

	if (opts.errflg)
		{
		fprintf(stderr, "usage: %s\n", usage_message);
		fprintf(stderr, "\nProgram <%s> Terminated\n", program_name);
		error = MB_ERROR_BAD_USAGE;
		exit(error);
		}

	/* print starting debug statements */
	if (opts.verbose >= 1)
		{
		print_mbdefaults(opts.verbose, &opts, &mbdflts, &error);
		}

	/* if help desired then print it and exit */
	if (opts.help)
		{
		fprintf(stderr, "\nProgram %s\n", program_name);
		fprintf(stderr, "Version %s\n", rcs_id);
		fprintf(stderr, "MB-system Version %s\n", MB_VERSION);
		fprintf(stderr, "\nusage: %s\n", usage_message);
		fprintf(stderr, "\n%s\n", help_message);
		exit(error);
		}
		
	/* get format if required */
	if (opts.format == 0)
		{
		mb_get_format(opts.verbose, opts.read_file, NULL, &(opts.format),
			&error);
		}

	/* determine whether to read one file or a list of files */
	if (opts.format < 0)
		{
		read_datalist = MB_YES;
		}

	/* open file list */
	if (read_datalist == MB_YES)
		{
		if ((status =
			mb_datalist_open(opts.verbose, &datalist, opts.read_file,
				look_processed, &error)) != MB_SUCCESS)
			{
			char message[MAX_ERROR_STRING];
			sprintf(message, "Unable to open data list file: %s\n",
				opts.read_file);
			error_exit(opts.verbose, MB_ERROR_OPEN_FAIL, "mb_datalist_open",
				message);
			}

		if ((status =
			mb_datalist_read(opts.verbose, datalist, ifile, &(opts.format),
				&file_weight, &error)) == MB_SUCCESS)
			{
			read_data = MB_YES;
			}
		else
			{
			read_data = MB_NO;
			}
		}
	/* else copy single filename to be read */
	else
		{
		strcpy(ifile, opts.read_file);
		read_data = MB_YES;
		}

	/* reset total record counter */
	zero_counts(opts.verbose, &totrecs, &error);

	/* loop over files to be read */
	while (read_data == MB_YES)
		{
		/* reset file record counter */
		zero_counts(opts.verbose, &filerecs, &error);

		/* process the output files */
		if (status == MB_SUCCESS)
			{
			status = process_output(opts.verbose, &mbdflts, &opts, ifile,
				&filerecs, &error);
			}

		/* output counts */
		filerecs.files_read++;
		if (opts.verbose >= 1)
			{
			fprintf(stdout, "\nData records read from: %s\n", ifile);
			print_counts(opts.verbose, &filerecs, &error);
			}

		/* add this file's counts to total */
		add_counts(opts.verbose, &totrecs, &filerecs, &error);

		/* figure out whether and what to read next */
		if (read_datalist == MB_YES)
			{
			if ((status =
				mb_datalist_read(opts.verbose, datalist, ifile, &(opts.format),
					&file_weight, &error)) == MB_SUCCESS)
				{
				read_data = MB_YES;
				}
			else
				{
				read_data = MB_NO;
				}
			}
		else
			{
			read_data = MB_NO;
			}
		}		/* end loop over files in list */

	/* output counts */
	if (opts.verbose >= 1)
		{
		fprintf(stdout, "\nTotal data records read:\n");
		print_counts(opts.verbose, &totrecs, &error);
		}

	if (read_datalist == MB_YES)
		{
		mb_datalist_close(opts.verbose, &datalist, &error);
		}

	/* check memory */
	status = mb_memory_list(opts.verbose, &error);

	/* mb_mem_debug_off(opts.verbose, &error); */

	return (status);
}	/* main */
Exemple #13
0
void update_links( void )
{
  char_data*            ch;
  link_data*          link;
  text_data*       receive;
  fd_set          read_set;
  fd_set         write_set;
  fd_set          exec_set;
  struct timeval     start;  
  struct timeval   timeout;  

  gettimeofday( &start, NULL );

  timeout.tv_sec  = 1;
  timeout.tv_usec = 0;

  FD_ZERO( &read_set );
  FD_ZERO( &write_set );
  FD_ZERO( &exec_set );

  FD_SET( socket_one, &read_set );
  FD_SET( socket_two, &read_set );

  for( link = link_list; link != NULL; link = link->next ) {
    FD_SET( link->channel, &read_set  );
    FD_SET( link->channel, &write_set );
    FD_SET( link->channel, &exec_set );
    }

  if( (int) select( FD_SETSIZE, &read_set, &write_set, &exec_set,
    &timeout ) < 0 ) 
    panic( "Update links: select" );

  if( FD_ISSET( socket_one, &read_set ) )
    open_link( socket_one );

  if( FD_ISSET( socket_two, &read_set ) )
    open_link( socket_two );

  for( link = link_list; link != NULL; link = link_next ) {
    link_next = link->next;
  
    if( FD_ISSET( link->channel, &exec_set ) ) {
      write( link->player );
      close_socket( link );
      continue;
      }
  
    if( FD_ISSET( link->channel, &read_set ) ) {
      link->idle = 0;
      if( link->player != NULL )
        link->player->timer = current_time;
      if( !read_link( link ) ) {
        write( link->player );
        close_socket( link );
        continue;
        }
      }

    if( link->idle++ > 10000 && link->connected != CON_PLAYING ) {
      send( link, "\n\r\n\r-- CONNECTION TIMEOUT --\n\r" );
      close_socket( link, TRUE );
      }
    }

  pulse_time[ TIME_READ_INPUT ] = stop_clock( start );  
  gettimeofday( &start, NULL );

  for( link = link_list; link != NULL; link = link_next ) {
    link_next = link->next;
    if( link->command = ( ( receive = link->receive ) != NULL ) ) {
      ampersand( receive );
      link->receive  = receive->next;
      link->idle     = 0; 
      if( link->connected == CON_PLAYING ) {
        stop_idling( ch = link->character );
        interpret( link->character, receive->message.text );
        }  
      else
        nanny( link, receive->message.text );
      delete receive;
      }
    }

  pulse_time[ TIME_COMMANDS ] = stop_clock( start );  
  gettimeofday( &start, NULL );

  for( link = link_list; link != NULL; link = link_next ) {
    link_next = link->next;
    if( link->idle%25 == 0 && FD_ISSET( link->channel, &write_set )
      && !process_output( link ) ) {
      write( link->player );
      close_socket( link );
      }
    }  
  
  pulse_time[ TIME_WRITE_OUTPUT ] = stop_clock( start );  

  return;
}
Exemple #14
0
void ProcessQueue::process_output_callback(const ProcessCommand& cmd, const char* buff, size_t count)
{
	emit process_output(QString::fromAscii(buff, count));
}
Exemple #15
0
int empire_init(DESC *d, int nargs, char *args[], int id)
{
  int sock_req;
  char buf[1024], buf2[80];
  char *pt, *pt2, *country, *password;

  // get country and password
  if ((nargs != 2) || (*args[0] == '\0') || (*args[1] == '\0')) {
    queue_string(d,"Bad arguments to empire door.");
    return -1;
  } 
  country = args[0];
  password = args[1];
  sprintf(buf2, "%s %s", "localhost", "1665");

/*pt = doorparm("empire"); */
  pt = buf2;

  if (*pt == '\0') {
    queue_string(desc_in_use, "Read of door parameters failed.\r\n");
    return -1;
  }
  pt2 = strchr(pt,' ');
  if (pt2 == NULL) {
    queue_string(desc_in_use, "Bad format in door parameters file.\r\n");
    return -1;
  }
  *pt2 = '\0';
  sock_req = door_tcp_connect(pt,pt2+1, d, id);

  if (sock_req < 0) {
    queue_string(desc_in_use, "Connection to empire server failed.\r\n");
    return -1;
  }

  if (!expect(sock_req, C_INIT, buf)) {
    queue_string(desc_in_use, "Login to empire server failed (stage 1).\r\n");
    close(sock_req);
    return -1;
  }
  strcpy(buf,Name(desc_in_use->player));
  strcat(buf,"@");
  strcat(buf,mudconf.mud_name);
  if (!sendcmd(sock_req, USER, buf)) {
    queue_string(desc_in_use, "Login to empire server failed (stage 2).\r\n");
    goto abort;
  }
  if (!expect(sock_req, C_CMDOK, buf)) {
    queue_string(desc_in_use, "Login to empire server failed (stage 3).\r\n");
    goto abort;
  }
  if (!sendcmd(sock_req, COUN, country)) {
    queue_string(desc_in_use, "Login to empire server failed (stage 4).\r\n");
    goto abort;
  }
  if (!expect(sock_req, C_CMDOK, buf)) {
    queue_string(desc_in_use, "Login to empire server failed. Posible bad country name. (stage 5).\r\n");
    goto abort;
  }
  if (!sendcmd(sock_req, PASS, password)) {
    queue_string(desc_in_use, "Login to empire server failed (stage 6).\r\n");
    goto abort;
  }
  if (!expect(sock_req, C_CMDOK, buf)) {
    queue_string(desc_in_use, "Login to empire server failed. Posible bad password. (stage 7).\r\n");
    goto abort;
  }
  if (!sendcmd(sock_req, PLAY, (char *)0)) {
    queue_string(desc_in_use, "Login to empire server failed (stage 8).\r\n");
    goto abort;
  }
  if (!expect(sock_req, C_INIT, buf)) {
    queue_string(desc_in_use, buf);
    queue_string(desc_in_use, "\r\n");
    queue_string(desc_in_use, "Login to empire server failed. (stage 9).\r\n");
    goto abort;
  }

  queue_string(desc_in_use, "\r\n\t-=O=-\r\n");
  process_output(desc_in_use);
  return 1;

 abort:
  free_lbuf(d->door_lbuf);
  free_mbuf(d->door_mbuf);
  close(sock_req);
  return -1;
}
Exemple #16
0
// thread main!
int uart_unix_main(void* arg)
{
    dthread_t* self = (dthread_t*) arg;
    dthread_t* other = (dthread_t*) self->arg;
    dmessage_t* mp = NULL;
    dthread_poll_event_t ev, *evp;
    size_t nev;
    dterm_t term;
    uart_ctx_t ctx;
    ErlDrvTermData mp_from;
    ErlDrvTermData mp_ref;
    dthread_t*     mp_source;
    int tmo;
    int r;

    DEBUGF("uart_unix: thread started");

    uart_init(&ctx, self, other);

    dterm_init(&term);

again_tmo:
    tmo = next_timeout(&ctx);
again:
    nev = 0;
    evp = NULL;
    if (ctx.fd >= 0) {
	ev.event = (ErlDrvEvent) ((long)ctx.fd);
	ev.events = 0;
	if ((ctx.option.active != UART_PASSIVE) || ctx.recv) {
	    ev.events |= ERL_DRV_READ;
	    if (ctx.option.ptypkt && (ctx.fd != ctx.tty_fd))
		ev.events |= ERL_DRV_EXCEP;
	}
	if (ctx.oq.mesg)
	    ev.events |= ERL_DRV_WRITE;
	if (ev.events) {
	    evp = &ev;
	    nev = 1;
	}
	DEBUGF("ctx.fd=%d, ev.events=%d", ctx.fd, ev.events);
    }

    DEBUGF("uart_unix_main: nev=%d, events=%x, timeout = %d", 
	   nev, ev.events, tmo);
    r = dthread_poll(self, evp, &nev, tmo);

    if (r < 0) {
	DEBUGF("uart_unix_main: dthread_poll failed=%d", r);
	goto again_tmo;
    }
    else {
	DEBUGF("uart_unix_main: nev=%d, r=%d", nev, r);

	if (evp && (nev == 1)) {
	    if (evp->revents & ERL_DRV_WRITE)
		process_output(&ctx, self);
	    if (evp->revents & (ERL_DRV_READ|ERL_DRV_EXCEP)) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	}
	tmo = next_timeout(&ctx);
	DEBUGF("uart_unix_main: timeout = %d", tmo);
	if (ctx.recv) {
	    if (tmo == 0) {
		uart_async_error_am(&ctx, ctx.dport, ctx.caller, am_timeout);
		clear_timeout(&ctx);
		ctx.remain = 0;
	    }
	}
	if (r == 0)
	    goto again;

	// r>0 (number of messages)
	DEBUGF("about to receive message r=%d", r);
	if ((mp = dthread_recv(self, NULL)) == NULL) {
	    DEBUGF("uart_unix_main: message was NULL");
	    goto again;
	}
	mp_from = mp->from;
	mp_ref  = mp->ref;
	mp_source = mp->source;

	switch (mp->cmd) {
	case DTHREAD_STOP:
	    DEBUGF("uart_unix_main: STOP");
	    close_device(&ctx);
	    uart_final(&ctx);
	    dmessage_free(mp);
	    DEBUGF("uart_unix_main: EXIT");
	    dthread_exit(0);
	    break;

	case DTHREAD_OUTPUT: // async send!
	    DEBUGF("uart_unix_main: OUTPUT");
	    if (ctx.fd < 0) {
		dmessage_free(mp);
		goto again;
	    }
	    if (enq_output(&ctx, self, mp, 0) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_CONNECT: {
	    ErlDrvTermData owner;
	    if (mp->used != 0) goto badarg;
	    owner = driver_connected(self->port);
	    self->owner   = owner;
	    other->owner  = owner;
	    goto ok;
	}

	case UART_CMD_CLOSE:
	    DEBUGF("uart_unix_main: CLOSE");
	    close_device(&ctx);
	    goto ok;

	case UART_CMD_SEND: // sync send
	    DEBUGF("uart_unix_main: SEND");
	    if (ctx.fd < 0) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;
	    
	case UART_CMD_SENDCHAR: // sync send
	    DEBUGF("uart_unix_main: SENDCHAR");
	    if (ctx.fd < 0) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_RECV: {  // <<Time:32, Length:32>> Time=0xffffffff=inf
	    uint32_t tm;
	    int len;
	    DEBUGF("uart_unix_main: RECV");
	    if (ctx.fd < 0) goto ebadf;
	    if (ctx.recv) goto ealready;
	    if (mp->used != 8) goto badarg;
	    if (ctx.option.active != UART_PASSIVE) goto badarg;
	    tm = get_uint32((uint8_t*) mp->buffer);
	    len = (int) get_uint32((uint8_t*) (mp->buffer+4));
	    if ((len < 0) || (len > UART_MAX_PACKET_SIZE)) goto badarg;
	    ctx.ref = mp_ref;
	    ctx.caller = mp_from;
	    set_timeout(&ctx, tm);
	    ctx.recv = 1;
	    DEBUGF("recv timeout %lu", tm);
	    process_input(&ctx, self, len);
	    dmessage_free(mp);
	    goto again_tmo;
	}

	case UART_CMD_UNRECV: {  // argument is data to push back
	    uart_buf_push(&ctx.ib, mp->buffer, mp->used);
	    DEBUGF("unrecived %d bytes", ctx.ib.ptr - ctx.ib.ptr_start);
	    if (ctx.option.active != UART_PASSIVE) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_SETOPTS: {
	    uart_com_state_t state  = ctx.state;
	    uart_opt_t       option = ctx.option;
	    uint32_t         sflags = ctx.sflags;

	    // parse & update options in state,option and sflag
	    if (uart_parse_opts(mp->buffer, mp->used, 
				&state, &option, &sflags) < 0)
		goto badarg;

	    //  apply the changed values
	    if ((r=apply_opts(&ctx, &state, &option, sflags)) < 0)
		goto error;

	    if (r == 1) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_GETOPTS: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    // {Ref, {ok,List}} || {Ref, {error,Reason}}
	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    if (uart_get_opts(&term, &ctx,(uint8_t*)mp->buffer,mp->used) < 0) {
			dterm_reset(&term);
			goto badarg;
		    }
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_GET_MODEM: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    uart_modem_state_t mstate;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (get_modem_state(ctx.tty_fd, &mstate) < 0) goto error;

	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    modem_state_dterm(&term, mstate);
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_SET_MODEM: {
	    uart_modem_state_t mstate;	    
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.tty_fd, mstate, 1) < 0) goto error;
	    goto ok;
	}

	case UART_CMD_CLR_MODEM: {
	    uart_modem_state_t mstate;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.tty_fd, mstate, 0) < 0) goto error;
	    goto ok;
	}
		
	case UART_CMD_HANGUP: {
	    struct termios tio;
	    int r;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 0) goto badarg;
	    if ((r = tcgetattr(ctx.tty_fd, &tio)) < 0) {
		INFOF("tcgetattr: error=%s\n", strerror(errno));
		goto badarg;
	    }
	    cfsetispeed(&tio, B0);
	    cfsetospeed(&tio, B0);
	    if ((r = tcsetattr(ctx.tty_fd, TCSANOW, &tio)) < 0) {
		INFOF("tcsetattr: error=%s\n", strerror(errno));
		goto badarg;		
	    }
	    goto ok;
	}
		
	case UART_CMD_BREAK: {
	    int duration;
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    duration = (int) get_uint32((uint8_t*) mp->buffer);
	    if (tcsendbreak(ctx.tty_fd, duration) < 0)
		goto error;
	    goto ok;
	}
	    
	case UART_CMD_FLOW:
	    if (ctx.tty_fd < 0) goto ebadf;
	    if (mp->used != 1) goto badarg;
	    switch(mp->buffer[0]) {
	    case 0: r = tcflow(ctx.tty_fd, TCIOFF); break;
	    case 1: r = tcflow(ctx.tty_fd, TCION); break;
	    case 2: r = tcflow(ctx.tty_fd, TCOOFF); break;
	    case 3: r = tcflow(ctx.tty_fd, TCOON); break;
	    default: goto badarg; break;
	    }
	    if (r < 0)
		goto error;
	    goto ok;

	default:
	    goto badarg;
	}
    }

ok:
    dthread_port_send_ok(mp_source, self,  mp_from, mp_ref);
    if (mp) dmessage_free(mp);
    goto again;

ebadf:
    errno = EBADF;
    goto error;
badarg:
    errno = EINVAL;
    goto error;
ealready:
    errno = EALREADY;
    goto error;

error:
    dthread_port_send_error(mp_source, self, mp_from, mp_ref,
			    uart_errno(&ctx));
    if (mp) dmessage_free(mp);
    goto again;
}
Exemple #17
0
// thread main!
int uart_win32_main(void* arg)
{
    dthread_t* self = (dthread_t*) arg;
    dthread_t* other = (dthread_t*) self->arg;
    dmessage_t* mp = NULL;
    dthread_poll_event_t ev[3];
    dthread_poll_event_t* evp;
    size_t nev;
    dterm_t term;
    uart_ctx_t ctx;
    ErlDrvTermData mp_from;
    ErlDrvTermData mp_ref;
    dthread_t*     mp_source;
    int tmo;
    int r;

    DEBUGF("uart_win32: thread started");

    uart_init(&ctx, self, other);

    dterm_init(&term);

again_tmo:
    tmo = next_timeout(&ctx);
again:
    nev = 0;

    if (ctx.writing) {
	ev[nev].event = (ErlDrvEvent) ctx.out.hEvent;
	ev[nev].events = ERL_DRV_READ; // yepp, even for write
	nev++;
    }

    while(!ctx.reading && (ctx.recv || (ctx.option.active != UART_PASSIVE)))
	process_input(&ctx, self, 0);

    if (ctx.reading) {
	ev[nev].event = (ErlDrvEvent) ctx.in.hEvent;
	ev[nev].events = ERL_DRV_READ;
	nev++;
    }

    evp = nev ? &ev[0] : NULL;

    DEBUGF("uart_win32_main: ctx.fh=%d, nev=%u, timeout = %d", 
	   ctx.fh, nev, tmo);
    r = dthread_poll(self, evp, &nev, tmo);

    if (r < 0) {
	DEBUGF("uart_win32_main: dthread_poll failed=%d", r);
	goto again_tmo;
    }
    else {
	DWORD i;
	DEBUGF("uart_win32_main: nev=%u, r=%d", nev, r);
	for (i = 0; i < nev; i++) {
	    if (ev[i].revents & ERL_DRV_READ) {
		if (ev[i].event == (ErlDrvEvent) ctx.in.hEvent) {
		    while((process_input(&ctx, self, 0) == 1) && 
			  (ctx.option.active != UART_PASSIVE))
			;
		}
		else if (ev[i].event == (ErlDrvEvent) ctx.out.hEvent) {
		    process_output(&ctx, self);
		}
	    }
	}
	tmo = next_timeout(&ctx);
	DEBUGF("uart_win32_main: timeout = %d", tmo);
	if (ctx.recv) {
	    if (tmo == 0) {
		uart_async_error_am(&ctx, ctx.dport, ctx.caller, am_timeout);
		clear_timeout(&ctx);
		ctx.remain = 0;
	    }
	}
	if (r == 0)
	    goto again;

	// r>0 (number of messages)
	DEBUGF("about to receive message r=%d", r);
	if ((mp = dthread_recv(self, NULL)) == NULL) {
	    DEBUGF("uart_win32_main: message was NULL");
	    goto again;
	}
	mp_from = mp->from;
	mp_ref  = mp->ref;
	mp_source = mp->source;

	switch (mp->cmd) {
	case DTHREAD_STOP:
	    DEBUGF("uart_win32_main: STOP");
	    close_device(&ctx);
	    uart_final(&ctx);
	    dmessage_free(mp);
	    DEBUGF("uart_win32_main: EXIT");
	    dthread_exit(0);
	    break;

	case DTHREAD_OUTPUT: // async send!
	    DEBUGF("uart_win32_main: OUTPUT");
	    if (ctx.fh == INVALID_HANDLE_VALUE) {
		dmessage_free(mp);
		goto again;
	    }
	    if (enq_output(&ctx, self, mp, 0) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_CONNECT: {
	    ErlDrvTermData owner;
	    if (mp->used != 0) goto badarg;
	    owner = driver_connected(self->port);
	    self->owner   = owner;
	    other->owner  = owner;
	    goto ok;
	}

	case UART_CMD_CLOSE:
	    DEBUGF("uart_win32_main: CLOSE");
	    close_device(&ctx);
	    goto ok;

	case UART_CMD_SEND: // sync send
	    DEBUGF("uart_win32_main: SEND");
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;
	    
	case UART_CMD_SENDCHAR: // sync send
	    DEBUGF("uart_win32_main: SENDCHAR");
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (enq_output(&ctx, self, mp, mp_from) < 0) {
		mp = NULL;
		goto error;
	    }
	    goto again;

	case UART_CMD_RECV: {  // <<Time:32, Length:32>> Time=0xffffffff=inf
	    uint32_t tm;
	    int len;
	    DEBUGF("uart_win32_main: RECV");
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (ctx.recv) goto ealready;
	    if (mp->used != 8) goto badarg;
	    if (ctx.option.active != UART_PASSIVE) goto badarg;
	    tm = get_uint32((uint8_t*) mp->buffer);
	    len = (int) get_uint32((uint8_t*) (mp->buffer+4));
	    if ((len < 0) || (len > UART_MAX_PACKET_SIZE)) goto badarg;
	    ctx.ref = mp_ref;
	    ctx.caller = mp_from;
	    set_timeout(&ctx, tm);
	    ctx.recv = 1;
	    DEBUGF("recv timeout %lu", tm);
	    process_input(&ctx, self, len);
	    dmessage_free(mp);
	    goto again_tmo;
	}

	case UART_CMD_UNRECV: {  // argument is data to push back
	    uart_buf_push(&ctx.ib, mp->buffer, mp->used);
	    DEBUGF("unrecived %d bytes", ctx.ib.ptr - ctx.ib.ptr_start);
	    if (ctx.option.active != UART_PASSIVE) {
		while((process_input(&ctx, self, 0) == 1) && 
		      (ctx.option.active != UART_PASSIVE))
		    ;
	    }
	    goto ok;
	}

	case UART_CMD_SETOPTS: {
	    uart_com_state_t state  = ctx.state;
	    uart_opt_t       option = ctx.option;
	    uint32_t         sflags = ctx.sflags;

	    // parse & update options in state,option and sflag
	    if (uart_parse_opts(mp->buffer, mp->used, 
				&state, &option, &sflags) < 0)
		goto badarg;

	    //  apply the changed values
	    if ((r=apply_opts(&ctx, &state, &option, sflags)) < 0) {
		goto error;
	    }
	    goto ok;
	}

	case UART_CMD_GETOPTS: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    // {Ref, {ok,List}} || {Ref, {error,Reason}}
	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    if (uart_get_opts(&term, &ctx,(uint8_t*)mp->buffer,mp->used) < 0) {
			dterm_reset(&term);
			goto badarg;
		    }
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_GET_MODEM: {
	    dterm_mark_t m1;
	    dterm_mark_t m2;
	    uart_modem_state_t mstate;
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (get_modem_state(ctx.fh, &mstate) < 0) goto error;

	    dterm_tuple_begin(&term, &m1); {
		dterm_uint(&term, mp_ref);
		dterm_tuple_begin(&term, &m2); {
		    dterm_atom(&term, am_ok);
		    modem_state_dterm(&term, mstate);
		}
		dterm_tuple_end(&term, &m2);
	    }
	    dterm_tuple_end(&term, &m1);
	    dthread_port_send_dterm(mp_source, self, mp_from, &term);
	    dterm_reset(&term);
	    dmessage_free(mp);
	    goto again;
	}

	case UART_CMD_SET_MODEM: {
	    uart_modem_state_t mstate;	    
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.fh, mstate, 1) < 0) goto error;
	    goto ok;
	}

	case UART_CMD_CLR_MODEM: {
	    uart_modem_state_t mstate;
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    mstate = (uart_modem_state_t) get_uint32((uint8_t*) mp->buffer);
	    if (set_modem_state(ctx.fh, mstate, 0) < 0) goto error;
	    goto ok;
	}
		
	case UART_CMD_HANGUP: {
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 0) goto badarg;
	    // FIXME?
	    goto ok;
	}
		
	case UART_CMD_BREAK: {
	    int duration;
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 4) goto badarg;
	    duration = (int) get_uint32((uint8_t*) mp->buffer);
	    if (!EscapeCommFunction(ctx.fh, SETBREAK)) {
		DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		goto error;
	    }
	    Sleep(duration);
	    if (!EscapeCommFunction(ctx.fh, CLRBREAK)) {
		DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		goto error;
	    }
	    goto ok;
	}

	case UART_CMD_FLOW:
	    if (ctx.fh == INVALID_HANDLE_VALUE) goto ebadf;
	    if (mp->used != 1) goto badarg;
	    switch(mp->buffer[0]) {
	    case 0:
		if (!EscapeCommFunction(ctx.fh, SETXOFF)) {
		    DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		    goto error;
		}
		break;
	    case 1:
		if (!EscapeCommFunction(ctx.fh, SETXON)) {
		    DEBUG_ERROR("EscapeCommFunction: error %d", GetLastError());
		    goto error;
		}
		break;
	    case 2:
		// TransmitCommChar(ctx.fh, XOFF);
		break;
	    case 3:
		// TransmitCommChar(ctx.fh, XON);
		break;
	    default: 
		goto badarg;
	    }
	    goto ok;

	default:
	    goto badarg;
	}
    }

ok:
    dthread_port_send_ok(mp_source, self,  mp_from, mp_ref);
    if (mp) dmessage_free(mp);
    goto again;

ebadf:
    errno = EBADF;
    goto error;
badarg:
    errno = EINVAL;
    goto error;
ealready:
    errno = EBUSY;
    goto error;

error:
    dthread_port_send_error(mp_source, self, mp_from, mp_ref,
			    uart_errno(&ctx));
    if (mp) dmessage_free(mp);
    goto again;
}
Exemple #18
0
static gavl_source_status_t
read_frame_internal(void * sp, gavl_audio_frame_t ** frame, int num_samples)
  {
  gavl_audio_source_t * s = sp;
  int samples_read = s->incomplete_samples;
  int samples_copied;
  gavl_source_status_t ret = GAVL_SOURCE_OK;
  int eat_all = 0;
  
  s->incomplete_samples = 0;
  
  
  while(samples_read < num_samples)
    {
    /* Read new frame if neccesary */
    if(!s->frame || !s->frame->valid_samples)
      {
      eat_all = 0;
      /* Check for passthrough */
      if(s->flags & FLAG_PASSTHROUGH)
        {
        if((*frame && !(s->src_flags & GAVL_SOURCE_SRC_ALLOC)) ||
           (!(*frame) && (s->src_flags & GAVL_SOURCE_SRC_ALLOC)))
          {
          ret = do_read(s, frame);
          if(ret == GAVL_SOURCE_OK)
            {
            process_input(s, *frame);
            process_output(s, *frame);
            }
          return ret;
          }
        }
      if(s->flags & FLAG_DO_CONVERT)
        {
        gavl_audio_frame_t * in_frame;
      
        if(s->src_flags & GAVL_SOURCE_SRC_ALLOC)
          in_frame = NULL;
        else
          {
          if(!s->in_frame)
            s->in_frame = gavl_audio_frame_create(&s->src_format);
          in_frame = s->in_frame;
          }
        
        ret = do_read(s, &in_frame);
        
        if(ret != GAVL_SOURCE_OK)
          break;
        
        if(!process_input(s, in_frame))
          continue;
        
        /* Get out frame */
        check_out_frame(s);
        gavl_audio_convert(s->cnv, in_frame, s->out_frame);
        s->frame = s->out_frame;
#if 0        
        if(s->src_format.samplerate != s->dst_format.samplerate)
          fprintf(stderr, "Converted frame (resample) %d %d\n",
                  in_frame->valid_samples, s->out_frame->valid_samples);
#endif
        }
      else
        {
        if(s->src_flags & GAVL_SOURCE_SRC_ALLOC)
          {
          s->frame = NULL;
          ret = do_read(s, &s->frame);
          if(ret != GAVL_SOURCE_OK)
            break;
          
          if(!process_input(s, s->frame))
            continue;
          eat_all = 1;
          }
        else
          {
          check_out_frame(s);
          ret = do_read(s, &s->out_frame);
          if(ret != GAVL_SOURCE_OK)
            break;
          s->frame = s->out_frame;
          if(!process_input(s, s->frame))
            continue;
          }
        }
      s->frame_samples = s->frame->valid_samples;
      }

    /* Make sure we have a frame to write to */
    if(!(*frame))
      {
      if(!s->dst_frame)
        s->dst_frame = gavl_audio_frame_create(&s->dst_format);
      *frame = s->dst_frame;
      }
    
    /* Copy samples */
    
    samples_copied =
      gavl_audio_frame_copy(&s->dst_format,
                            *frame,                                     // dst
                            s->frame,                                   // src
                            samples_read,                               // dst_pos
                            s->frame_samples - s->frame->valid_samples, // src_pos
                            num_samples - samples_read,                 // dst_size
                            s->frame->valid_samples);                   // src_size
    s->frame->valid_samples -= samples_copied;
    samples_read += samples_copied;
    }
  
  if(ret == GAVL_SOURCE_AGAIN)
    {
    s->incomplete_samples = samples_read;
    return GAVL_SOURCE_AGAIN;
    }
  
  if(samples_read)
    {
    ret = GAVL_SOURCE_OK;
    (*frame)->valid_samples = samples_read;
    process_output(s, *frame);

    /* Buffer samples for next time (we need to eat up all samples in this call) */
    if(eat_all && s->frame->valid_samples)
      {
      if(!s->buffer_frame)
        s->buffer_frame = gavl_audio_frame_create(&s->src_format);
      
      s->buffer_frame->valid_samples = 
        gavl_audio_frame_copy(&s->src_format,
                              s->buffer_frame,                            // dst
                              s->frame,                                   // src
                              0,                                          // dst_pos
                              s->frame_samples - s->frame->valid_samples, // src_pos
                              s->src_format.samples_per_frame,           // dst_size
                              s->frame->valid_samples);                   // src_size
      
      s->frame = s->buffer_frame;
      s->frame_samples = s->frame->valid_samples;
      }
    }
  else if(*frame)
    (*frame)->valid_samples = 0;
  
  return ret;
  }
Exemple #19
0
int main(int argc, char *argv[])
{
    struct AVMD5 *md5;
    AVFilterGraph *graph;
    AVFilterContext *src, *sink;
    AVFrame *frame;
    uint8_t errstr[1024];
    float duration;
    int err, nb_frames, i;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <duration>\n", argv[0]);
        return 1;
    }

    duration  = atof(argv[1]);
    nb_frames = duration * INPUT_SAMPLERATE / FRAME_SIZE;
    if (nb_frames <= 0) {
        fprintf(stderr, "Invalid duration: %s\n", argv[1]);
        return 1;
    }

    avfilter_register_all();

    /* Allocate the frame we will be using to store the data. */
    frame  = av_frame_alloc();
    if (!frame) {
        fprintf(stderr, "Error allocating the frame\n");
        return 1;
    }

    md5 = av_md5_alloc();
    if (!md5) {
        fprintf(stderr, "Error allocating the MD5 context\n");
        return 1;
    }

    /* Set up the filtergraph. */
    err = init_filter_graph(&graph, &src, &sink);
    if (err < 0) {
        fprintf(stderr, "Unable to init filter graph:");
        goto fail;
    }

    /* the main filtering loop */
    for (i = 0; i < nb_frames; i++) {
        /* get an input frame to be filtered */
        err = get_input(frame, i);
        if (err < 0) {
            fprintf(stderr, "Error generating input frame:");
            goto fail;
        }

        /* Send the frame to the input of the filtergraph. */
        err = av_buffersrc_add_frame(src, frame);
        if (err < 0) {
            av_frame_unref(frame);
            fprintf(stderr, "Error submitting the frame to the filtergraph:");
            goto fail;
        }

        /* Get all the filtered output that is available. */
        while ((err = av_buffersink_get_frame(sink, frame)) >= 0) {
            /* now do something with our filtered frame */
            err = process_output(md5, frame);
            if (err < 0) {
                fprintf(stderr, "Error processing the filtered frame:");
                goto fail;
            }
            av_frame_unref(frame);
        }

        if (err == AVERROR(EAGAIN)) {
            /* Need to feed more frames in. */
            continue;
        } else if (err == AVERROR_EOF) {
            /* Nothing more to do, finish. */
            break;
        } else if (err < 0) {
            /* An error occurred. */
            fprintf(stderr, "Error filtering the data:");
            goto fail;
        }
    }

    avfilter_graph_free(&graph);
    av_frame_free(&frame);
    av_freep(&md5);

    return 0;

fail:
    av_strerror(err, errstr, sizeof(errstr));
    fprintf(stderr, "%s\n", errstr);
    return 1;
}
/*
 * Performs the interactive session.  This handles data transmission between
 * the client and the program.  Note that the notion of stdin, stdout, and
 * stderr in this function is sort of reversed: this function writes to
 * stdin (of the child program), and reads from stdout and stderr (of the
 * child program).
 */
void
server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg)
{
	fd_set *readset = NULL, *writeset = NULL;
	int max_fd = 0;
	u_int nalloc = 0;
	int wait_status;	/* Status returned by wait(). */
	pid_t wait_pid;		/* pid returned by wait(). */
	int waiting_termination = 0;	/* Have displayed waiting close message. */
	u_int64_t max_time_milliseconds;
	u_int previous_stdout_buffer_bytes;
	u_int stdout_buffer_bytes;
	int type;

	debug("Entering interactive session.");

	/* Initialize the SIGCHLD kludge. */
	child_terminated = 0;
	mysignal(SIGCHLD, sigchld_handler);

	if (!use_privsep) {
		signal(SIGTERM, sigterm_handler);
		signal(SIGINT, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);
	}

	/* Initialize our global variables. */
	fdin = fdin_arg;
	fdout = fdout_arg;
	fderr = fderr_arg;

	/* nonblocking IO */
	set_nonblock(fdin);
	set_nonblock(fdout);
	/* we don't have stderr for interactive terminal sessions, see below */
	if (fderr != -1)
		set_nonblock(fderr);

	if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin))
		fdin_is_tty = 1;

	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	notify_setup();

	previous_stdout_buffer_bytes = 0;

	/* Set approximate I/O buffer size. */
	if (packet_is_interactive())
		buffer_high = 4096;
	else
		buffer_high = 64 * 1024;

#if 0
	/* Initialize max_fd to the maximum of the known file descriptors. */
	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, fdin);
	max_fd = MAX(max_fd, fdout);
	if (fderr != -1)
		max_fd = MAX(max_fd, fderr);
#endif

	/* Initialize Initialize buffers. */
	buffer_init(&stdin_buffer);
	buffer_init(&stdout_buffer);
	buffer_init(&stderr_buffer);

	/*
	 * If we have no separate fderr (which is the case when we have a pty
	 * - there we cannot make difference between data sent to stdout and
	 * stderr), indicate that we have seen an EOF from stderr.  This way
	 * we don't need to check the descriptor everywhere.
	 */
	if (fderr == -1)
		fderr_eof = 1;

	server_init_dispatch();

	/* Main loop of the server for the interactive session mode. */
	for (;;) {

		/* Process buffered packets from the client. */
		process_buffered_input_packets();

		/*
		 * If we have received eof, and there is no more pending
		 * input data, cause a real eof by closing fdin.
		 */
		if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) {
			if (fdin != fdout)
				close(fdin);
			else
				shutdown(fdin, SHUT_WR); /* We will no longer send. */
			fdin = -1;
		}
		/* Make packets from buffered stderr data to send to the client. */
		make_packets_from_stderr_data();

		/*
		 * Make packets from buffered stdout data to send to the
		 * client. If there is very little to send, this arranges to
		 * not send them now, but to wait a short while to see if we
		 * are getting more data. This is necessary, as some systems
		 * wake up readers from a pty after each separate character.
		 */
		max_time_milliseconds = 0;
		stdout_buffer_bytes = buffer_len(&stdout_buffer);
		if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 &&
		    stdout_buffer_bytes != previous_stdout_buffer_bytes) {
			/* try again after a while */
			max_time_milliseconds = 10;
		} else {
			/* Send it now. */
			make_packets_from_stdout_data();
		}
		previous_stdout_buffer_bytes = buffer_len(&stdout_buffer);

		/* Send channel data to the client. */
		if (packet_not_very_much_data_to_write())
			channel_output_poll();

		/*
		 * Bail out of the loop if the program has closed its output
		 * descriptors, and we have no more data to send to the
		 * client, and there is no pending buffered data.
		 */
		if (fdout_eof && fderr_eof && !packet_have_data_to_write() &&
		    buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) {
			if (!channel_still_open())
				break;
			if (!waiting_termination) {
				const char *s = "Waiting for forwarded connections to terminate... (press ~& to background)\r\n";
				char *cp;
				waiting_termination = 1;
				buffer_append(&stderr_buffer, s, strlen(s));

				/* Display list of open channels. */
				cp = channel_open_message();
				buffer_append(&stderr_buffer, cp, strlen(cp));
				free(cp);
			}
		}
		max_fd = MAX(connection_in, connection_out);
		max_fd = MAX(max_fd, fdin);
		max_fd = MAX(max_fd, fdout);
		max_fd = MAX(max_fd, fderr);
		max_fd = MAX(max_fd, notify_pipe[0]);

		/* Sleep in select() until we can do something. */
		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, max_time_milliseconds);

		if (received_sigterm) {
			logit("Exiting on signal %d", (int)received_sigterm);
			/* Clean up sessions, utmp, etc. */
			cleanup_exit(255);
		}

		/* Process any channel events. */
		channel_after_select(readset, writeset);

		/* Process input from the client and from program stdout/stderr. */
		process_input(readset);

		/* Process output to the client and to program stdin. */
		process_output(writeset);
	}
	free(readset);
	free(writeset);

	/* Cleanup and termination code. */

	/* Wait until all output has been sent to the client. */
	drain_output();

	debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.",
	    stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes);

	/* Free and clear the buffers. */
	buffer_free(&stdin_buffer);
	buffer_free(&stdout_buffer);
	buffer_free(&stderr_buffer);

	/* Close the file descriptors. */
	if (fdout != -1)
		close(fdout);
	fdout = -1;
	fdout_eof = 1;
	if (fderr != -1)
		close(fderr);
	fderr = -1;
	fderr_eof = 1;
	if (fdin != -1)
		close(fdin);
	fdin = -1;

	channel_free_all();

	/* We no longer want our SIGCHLD handler to be called. */
	mysignal(SIGCHLD, SIG_DFL);

	while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0)
		if (errno != EINTR)
			packet_disconnect("wait: %.100s", strerror(errno));
	if (wait_pid != pid)
		error("Strange, wait returned pid %ld, expected %ld",
		    (long)wait_pid, (long)pid);

	/* Check if it exited normally. */
	if (WIFEXITED(wait_status)) {
		/* Yes, normal exit.  Get exit status and send it to the client. */
		debug("Command exited with status %d.", WEXITSTATUS(wait_status));
		packet_start(SSH_SMSG_EXITSTATUS);
		packet_put_int(WEXITSTATUS(wait_status));
		packet_send();
		packet_write_wait();

		/*
		 * Wait for exit confirmation.  Note that there might be
		 * other packets coming before it; however, the program has
		 * already died so we just ignore them.  The client is
		 * supposed to respond with the confirmation when it receives
		 * the exit status.
		 */
		do {
			type = packet_read();
		}
		while (type != SSH_CMSG_EXIT_CONFIRMATION);

		debug("Received exit confirmation.");
		return;
	}
	/* Check if the program terminated due to a signal. */
	if (WIFSIGNALED(wait_status))
		packet_disconnect("Command terminated on signal %d.",
				  WTERMSIG(wait_status));

	/* Some weird exit cause.  Just exit. */
	packet_disconnect("wait returned status %04x.", wait_status);
	/* NOTREACHED */
}
static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
			   const unsigned char *buf, size_t nr)
{
	const unsigned char *b = buf;
	DECLARE_WAITQUEUE(wait, current);
	int c;
	ssize_t retval = 0;

	
	if (L_TOSTOP(tty) && file->f_op->write != redirected_tty_write) {
		retval = tty_check_change(tty);
		if (retval)
			return retval;
	}

	
	process_echoes(tty);

	add_wait_queue(&tty->write_wait, &wait);
	while (1) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (signal_pending(current)) {
			retval = -ERESTARTSYS;
			break;
		}
		if (tty_hung_up_p(file) || (tty->link && !tty->link->count)) {
			retval = -EIO;
			break;
		}
		if (O_OPOST(tty) && !(test_bit(TTY_HW_COOK_OUT, &tty->flags))) {
			while (nr > 0) {
				ssize_t num = process_output_block(tty, b, nr);
				if (num < 0) {
					if (num == -EAGAIN)
						break;
					retval = num;
					goto break_out;
				}
				b += num;
				nr -= num;
				if (nr == 0)
					break;
				c = *b;
				if (process_output(c, tty) < 0)
					break;
				b++; nr--;
			}
			if (tty->ops->flush_chars)
				tty->ops->flush_chars(tty);
		} else {
			while (nr > 0) {
				c = tty->ops->write(tty, b, nr);
				if (c < 0) {
					retval = c;
					goto break_out;
				}
				if (!c)
					break;
				b += c;
				nr -= c;
			}
		}
		if (!nr)
			break;
		if (file->f_flags & O_NONBLOCK) {
			retval = -EAGAIN;
			break;
		}
		schedule();
	}
break_out:
	__set_current_state(TASK_RUNNING);
	remove_wait_queue(&tty->write_wait, &wait);
	if (b - buf != nr && tty->fasync)
		set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
	return (b - buf) ? b - buf : retval;
}
Exemple #22
0
int main(int argc, char **argv)
{
    String *cmd = string_new(0);
    String *input = NULL;

    if (argc == 1)
    {
        fprintf(stderr,
            "Usage: %s [-s] prog [arg(s)]\n"
            "      -s: use system call, not std-input\n"
            "    prog: program or system call to execute\n"
            "  arg(s): optional arguments to prog\n"
            "Input to prog is read from stdin, unless -s was specified\n"
            "   (don't make this too long, it's stored in a String first)\n"
            "\n",
            argv[0]);

        exit(1);
    }

    bool syscall = !strcmp(argv[1], "-s");
    if (syscall)
    {
        argc--;
        argv++;
    }
    else
    {
        input = string_new(0);
        char buffer[100];

        fprintf(stderr, "Reading input from stdin...\n");

        while (fgets(buffer, 100, stdin))
            string_addstr(input, buffer);

        fprintf(stderr, "Input will be:\n"
                        "`%s'\n", string_str(input));
    }

    while (*++argv)
    {
        string_addstr(cmd, *argv);
        string_addchar(cmd, ' ');
    }


    fprintf(stderr, "Command will be:\n"
                        "`%s'\n", string_str(cmd));

    message_setseverity(MSG_ALL);
    message(MSG_NOTICE, "Creating Process");

    Process process;
    process_construct(&process, "process-demo", cmd,
                                                input);

    if (syscall)
        process_system(&process);
    else
        process_fork(&process);

    String const *out = process_output(&process);

    fprintf(stderr, "Output from process: '\n"
            "%s\n"
            "'\n", string_str(out));

    process_destroy(&process);

    return 0;
}
static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
{
	unsigned long flags;
	int parmrk;

	if (tty->raw) {
		put_tty_queue(c, tty);
		return;
	}

	if (I_ISTRIP(tty))
		c &= 0x7f;
	if (I_IUCLC(tty) && L_IEXTEN(tty))
		c = tolower(c);

	if (L_EXTPROC(tty)) {
		put_tty_queue(c, tty);
		return;
	}

	if (tty->stopped && !tty->flow_stopped && I_IXON(tty) &&
	    I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty) &&
	    c != INTR_CHAR(tty) && c != QUIT_CHAR(tty) && c != SUSP_CHAR(tty)) {
		start_tty(tty);
		process_echoes(tty);
	}

	if (tty->closing) {
		if (I_IXON(tty)) {
			if (c == START_CHAR(tty)) {
				start_tty(tty);
				process_echoes(tty);
			} else if (c == STOP_CHAR(tty))
				stop_tty(tty);
		}
		return;
	}

	if (!test_bit(c, tty->process_char_map) || tty->lnext) {
		tty->lnext = 0;
		parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
		if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
			
			if (L_ECHO(tty))
				process_output('\a', tty);
			return;
		}
		if (L_ECHO(tty)) {
			finish_erasing(tty);
			
			if (tty->canon_head == tty->read_head)
				echo_set_canon_col(tty);
			echo_char(c, tty);
			process_echoes(tty);
		}
		if (parmrk)
			put_tty_queue(c, tty);
		put_tty_queue(c, tty);
		return;
	}

	if (I_IXON(tty)) {
		if (c == START_CHAR(tty)) {
			start_tty(tty);
			process_echoes(tty);
			return;
		}
		if (c == STOP_CHAR(tty)) {
			stop_tty(tty);
			return;
		}
	}

	if (L_ISIG(tty)) {
		int signal;
		signal = SIGINT;
		if (c == INTR_CHAR(tty))
			goto send_signal;
		signal = SIGQUIT;
		if (c == QUIT_CHAR(tty))
			goto send_signal;
		signal = SIGTSTP;
		if (c == SUSP_CHAR(tty)) {
send_signal:
			if (!L_NOFLSH(tty)) {
				n_tty_flush_buffer(tty);
				tty_driver_flush_buffer(tty);
			}
			if (I_IXON(tty))
				start_tty(tty);
			if (L_ECHO(tty)) {
				echo_char(c, tty);
				process_echoes(tty);
			}
			if (tty->pgrp)
				kill_pgrp(tty->pgrp, signal, 1);
			return;
		}
	}

	if (c == '\r') {
		if (I_IGNCR(tty))
			return;
		if (I_ICRNL(tty))
			c = '\n';
	} else if (c == '\n' && I_INLCR(tty))
		c = '\r';

	if (tty->icanon) {
		if (c == ERASE_CHAR(tty) || c == KILL_CHAR(tty) ||
		    (c == WERASE_CHAR(tty) && L_IEXTEN(tty))) {
			eraser(c, tty);
			process_echoes(tty);
			return;
		}
		if (c == LNEXT_CHAR(tty) && L_IEXTEN(tty)) {
			tty->lnext = 1;
			if (L_ECHO(tty)) {
				finish_erasing(tty);
				if (L_ECHOCTL(tty)) {
					echo_char_raw('^', tty);
					echo_char_raw('\b', tty);
					process_echoes(tty);
				}
			}
			return;
		}
		if (c == REPRINT_CHAR(tty) && L_ECHO(tty) &&
		    L_IEXTEN(tty)) {
			unsigned long tail = tty->canon_head;

			finish_erasing(tty);
			echo_char(c, tty);
			echo_char_raw('\n', tty);
			while (tail != tty->read_head) {
				echo_char(tty->read_buf[tail], tty);
				tail = (tail+1) & (N_TTY_BUF_SIZE-1);
			}
			process_echoes(tty);
			return;
		}
		if (c == '\n') {
			if (tty->read_cnt >= N_TTY_BUF_SIZE) {
				if (L_ECHO(tty))
					process_output('\a', tty);
				return;
			}
			if (L_ECHO(tty) || L_ECHONL(tty)) {
				echo_char_raw('\n', tty);
				process_echoes(tty);
			}
			goto handle_newline;
		}
		if (c == EOF_CHAR(tty)) {
			if (tty->read_cnt >= N_TTY_BUF_SIZE)
				return;
			if (tty->canon_head != tty->read_head)
				set_bit(TTY_PUSH, &tty->flags);
			c = __DISABLED_CHAR;
			goto handle_newline;
		}
		if ((c == EOL_CHAR(tty)) ||
		    (c == EOL2_CHAR(tty) && L_IEXTEN(tty))) {
			parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty))
				 ? 1 : 0;
			if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk)) {
				if (L_ECHO(tty))
					process_output('\a', tty);
				return;
			}
			if (L_ECHO(tty)) {
				
				if (tty->canon_head == tty->read_head)
					echo_set_canon_col(tty);
				echo_char(c, tty);
				process_echoes(tty);
			}
			if (parmrk)
				put_tty_queue(c, tty);

handle_newline:
			spin_lock_irqsave(&tty->read_lock, flags);
			set_bit(tty->read_head, tty->read_flags);
			put_tty_queue_nolock(c, tty);
			tty->canon_head = tty->read_head;
			tty->canon_data++;
			spin_unlock_irqrestore(&tty->read_lock, flags);
			kill_fasync(&tty->fasync, SIGIO, POLL_IN);
			if (waitqueue_active(&tty->read_wait))
				wake_up_interruptible(&tty->read_wait);
			return;
		}
	}

	parmrk = (c == (unsigned char) '\377' && I_PARMRK(tty)) ? 1 : 0;
	if (tty->read_cnt >= (N_TTY_BUF_SIZE - parmrk - 1)) {
		
		if (L_ECHO(tty))
			process_output('\a', tty);
		return;
	}
	if (L_ECHO(tty)) {
		finish_erasing(tty);
		if (c == '\n')
			echo_char_raw('\n', tty);
		else {
			
			if (tty->canon_head == tty->read_head)
				echo_set_canon_col(tty);
			echo_char(c, tty);
		}
		process_echoes(tty);
	}

	if (parmrk)
		put_tty_queue(c, tty);

	put_tty_queue(c, tty);
}
Exemple #24
0
void
server_loop2(Authctxt *authctxt)
{
    fd_set *readset = NULL, *writeset = NULL;
    int rekeying = 0, max_fd, nalloc = 0;
    double start_time, total_time;

    debug("Entering interactive session for SSH2.");
    start_time = get_current_time();

    mysignal(SIGCHLD, sigchld_handler);
    child_terminated = 0;
    connection_in = packet_get_connection_in();
    connection_out = packet_get_connection_out();

    if (!use_privsep) {
        signal(SIGTERM, sigterm_handler);
        signal(SIGINT, sigterm_handler);
        signal(SIGQUIT, sigterm_handler);
    }

    notify_setup();

    max_fd = MAX(connection_in, connection_out);
    max_fd = MAX(max_fd, notify_pipe[0]);

    server_init_dispatch();

    for (;;) {
        process_buffered_input_packets();

        rekeying = (xxx_kex != NULL && !xxx_kex->done);

        if (!rekeying && packet_not_very_much_data_to_write())
            channel_output_poll();
        wait_until_can_do_something(&readset, &writeset, &max_fd,
                                    &nalloc, 0);

        if (received_sigterm) {
            logit("Exiting on signal %d", received_sigterm);
            /* Clean up sessions, utmp, etc. */
            cleanup_exit(255);
        }

        collect_children();
        if (!rekeying) {
            channel_after_select(readset, writeset);
            if (packet_need_rekeying()) {
                debug("need rekeying");
                xxx_kex->done = 0;
                kex_send_kexinit(xxx_kex);
            }
        }
        process_input(readset);
        if (connection_closed)
            break;
        process_output(writeset);
    }
    collect_children();

    if (readset)
        xfree(readset);
    if (writeset)
        xfree(writeset);

    /* free all channels, no more reads and writes */
    channel_free_all();

    /* free remaining sessions, e.g. remove wtmp entries */
    session_destroy_all(NULL);
    total_time = get_current_time() - start_time;
    logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
          get_remote_ipaddr(), get_remote_port(),
          stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time,
          fdout_bytes / total_time);
}
void
server_loop2(Authctxt *authctxt)
{
	fd_set *readset = NULL, *writeset = NULL;
	int rekeying = 0, max_fd;
	u_int nalloc = 0;
	u_int64_t rekey_timeout_ms = 0;

	debug("Entering interactive session for SSH2.");

	mysignal(SIGCHLD, sigchld_handler);
	child_terminated = 0;
	connection_in = packet_get_connection_in();
	connection_out = packet_get_connection_out();

	if (!use_privsep) {
		signal(SIGTERM, sigterm_handler);
		signal(SIGINT, sigterm_handler);
		signal(SIGQUIT, sigterm_handler);
	}

	notify_setup();

	max_fd = MAX(connection_in, connection_out);
	max_fd = MAX(max_fd, notify_pipe[0]);

	server_init_dispatch();
	for (;;) {
		process_buffered_input_packets();

		rekeying = (xxx_kex != NULL && !xxx_kex->done);

		if (!rekeying && packet_not_very_much_data_to_write())
			channel_output_poll();
		if (options.rekey_interval > 0 && compat20 && !rekeying)
			rekey_timeout_ms = packet_get_rekey_timeout() * 1000;
		else
			rekey_timeout_ms = 0;

		wait_until_can_do_something(&readset, &writeset, &max_fd,
		    &nalloc, rekey_timeout_ms);

		if (received_sigterm) {
			logit("Exiting on signal %d", (int)received_sigterm);
			/* Clean up sessions, utmp, etc. */
			cleanup_exit(255);
		}

		collect_children();
		if (!rekeying) {
			channel_after_select(readset, writeset);
			if (packet_need_rekeying()) {
				debug("need rekeying");
				xxx_kex->done = 0;
				kex_send_kexinit(xxx_kex);
			}
		}
		process_input(readset);
		if (connection_closed)
			break;
		process_output(writeset);
	}
	collect_children();

	free(readset);
	free(writeset);

	/* free all channels, no more reads and writes */
	channel_free_all();

	/* free remaining sessions, e.g. remove wtmp entries */
	session_destroy_all(NULL);
}
Exemple #26
0
void game_loop( void )
{
   struct timeval last_time;

   gettimeofday( &last_time, NULL );
   current_time = last_time.tv_sec;

   // Main loop 
   while( !mud_down )
   {
      accept_new( control );

      // Primative, yet effective infinite loop catcher. At least that's the idea.
      set_alarm( 30 );
      alarm_section = "game_loop";

      // If no descriptors are present, why bother processing input for them?
      if( dlist.size(  ) > 0 )
         process_input(  );

#if !defined(__CYGWIN__)
#ifdef MULTIPORT
      mud_recv_message(  );
#endif
#endif
#ifdef IMC
      imc_loop(  );
#endif

      // Autonomous game motion. Stops processing when there are no people at all online.
      if( dlist.size(  ) > 0 )
         update_handler(  );

      // Event handling. Will continue to process even with nobody around. Keeps areas fresh this way.
      run_events( current_time );

      // If no descriptors are present, why bother processing output for them?
      if( dlist.size(  ) > 0 )
         process_output(  );

      /*
       * Synchronize to a clock. ( Would have moved this to its own function, but the code REALLY hated that plan.... )
       * Sleep( last_time + 1/PULSE_PER_SECOND - now ).
       * Careful here of signed versus unsigned arithmetic.
       */
      {
         struct timeval now_time;
         long secDelta;
         long usecDelta;

         gettimeofday( &now_time, NULL );
         usecDelta = ( last_time.tv_usec ) - ( now_time.tv_usec ) + 1000000 / sysdata->pulsepersec;
         secDelta = ( last_time.tv_sec ) - ( now_time.tv_sec );
         while( usecDelta < 0 )
         {
            usecDelta += 1000000;
            secDelta -= 1;
         }

         while( usecDelta >= 1000000 )
         {
            usecDelta -= 1000000;
            secDelta += 1;
         }

         if( secDelta > 0 || ( secDelta == 0 && usecDelta > 0 ) )
         {
            struct timeval stall_time;

            stall_time.tv_usec = usecDelta;
            stall_time.tv_sec = secDelta;
            if( select( 0, NULL, NULL, NULL, &stall_time ) < 0 && errno != EINTR )
            {
               perror( "game_loop: select: stall" );
               exit( 1 );
            }
         }
      }
      gettimeofday( &last_time, NULL );
      current_time = last_time.tv_sec;

      // Dunno if it needs to be reset, but I'll do it anyway. End of the loop here. 
      set_alarm( 0 );

      /*
       * This will be the very last thing done here, because if you can't make it through
       * one lousy loop without crashing a second time.....
       */
      sigsegv = false;
   }
   // End of main game loop 
   // Returns back to 'main', and will result in mud shutdown
}