Пример #1
0
/*
The 'channel_fork' function is used to create a new process.
Function creates 3 pipes from/to child:
fd[0] is pipe to childs standard input
fd[1] is pipe from childs standard output
fd[2] is pipe from childs error output
Function returns also childs PID.
*/
long long channel_fork(int fd[3]) {

    int pi[2], pa[3], ch[3];
    long long i, pid;

    for (i = 0; i < 3; ++i) pa[i] = ch[i] = fd[i] = -1;
    for (i = 0; i < 3; ++i) {
        if (open_pipe(pi) == -1) goto cleanup;
        pa[i] = pi[i ? 0 : 1];
        ch[i] = pi[i ? 1 : 0];
    }

    pid = fork();
    if (pid == -1) goto cleanup;
    if (pid == 0) {
        for (i = 0; i < 3; ++i) {
            close(pa[i]); close(i);
            blocking_enable(ch[i]);
            if (dup(ch[i]) != i) _exit(111);
        }
        return 0;
    }
    for (i = 0; i < 3; ++i) {
        close(ch[i]);
        fd[i] = pa[i];
    }

    return pid;

cleanup:
    for (i = 0; i < 3; ++i) { close(pa[i]); close(ch[i]); }
    return -1;
}
Пример #2
0
static int spawn_worker(char *cmd) 
{
	/* params struct for both workers */
	struct worker_params params;
	/* children's pids */
	pid_t c1, c2;
	int status, ret = 0;

	trim(cmd);
	params.cmd = cmd;

	if(open_pipe(params.pipe) == -1) {
		(void) fprintf(stderr, "%s: Could not create pipe\n", pgname);
		return -1;
	}

	/* We flush all our standard fd's so we'll have them empty in the workers */
	fflush(stdin);
	fflush(stdout);
	fflush(stderr);

	/* Fork execute worker */
	if((c1 = fork_function(execute, &params)) == -1) {
		(void) fprintf(stderr, "%s: Could not spawn execute worker\n", pgname);
		close_pipe(params.pipe, channel_all);
		return -1;
	}

	/* Fork format worker */
	if((c2 = fork_function(format, &params)) == -1) {
		(void) fprintf(stderr, "%s: Could not spawn format worker\n", pgname);
		/* Wait for child 1 */
		if(wait_for_child(c1) == -1) {
			(void) fprintf(stderr, "%s: Error waiting for execute worker to finish\n", pgname);
		}
		close_pipe(params.pipe, channel_all);
		return -1;
	}

	/* We need to close the pipe in parent, so that the format worker will quit working when execute's output has finished */
	close_pipe(params.pipe, channel_all);
	
	if((status = wait_for_child(c1)) != 0) {
		(void) fprintf(stderr, "%s: Execute worker returned %d\n", pgname, status);
		/* not neccessarily an error. If there was a typo in cmd don't quit the whole programm */
	//	ret = -1;
	}

	if((status = wait_for_child(c2)) != 0) {
		(void) fprintf(stderr, "%s: Format worker returned %d\n", pgname, status);
	//	ret = -1;
	}
	
	return ret;
}
Пример #3
0
/* test if close-on-exec works for open_pipe() */
static void test3(void) {

    int fd, pi[2];

    close(0);
    close(1);
    fd = open_pipe(pi);
    if (fd == -1) fail("unable to open pipe");
    if (pi[0] != 0) fail("unable to open pipe");
    if (pi[1] != 1) fail("unable to open pipe");
    cat();
}
Пример #4
0
/* Daemon init sequence */
void
open_bfd_pipes(void)
{
#ifdef _WITH_VRRP_
	/* Open BFD VRRP control pipe */
	if (open_pipe(bfd_vrrp_event_pipe) == -1) {
		log_message(LOG_ERR, "Unable to create BFD vrrp event pipe: %m");
		stop_keepalived();
		return;
	}
#endif

#ifdef _WITH_LVS_
	/* Open BFD checker control pipe */
	if (open_pipe(bfd_checker_event_pipe) == -1) {
		log_message(LOG_ERR, "Unable to create BFD checker event pipe: %m");
		stop_keepalived();
		return;
	}
#endif
}
Пример #5
0
static FILE *plugin_open(const char *path, const char *mode){
	int sfd;
	int ret;
	struct addrinfo hints,*rp,*result;
	char *url,*port,*filename;

	if(open_pipe())
		return NULL;

	if(parse_url(path,&url,&port,&filename)){
		return NULL;
	}

	memset(&hints,0,sizeof(struct addrinfo));
	hints.ai_family=AF_INET;
	hints.ai_socktype=SOCK_STREAM;
	hints.ai_protocol=0;
	if((ret=getaddrinfo(url,port,&hints,&result))){
		fprintf(stderr,"error (%s) - getaddrinfo: %s\n",path,gai_strerror(ret));
		close_pipe();
		free(port);
		return NULL;
	}
	free(url);
	free(port);

	for(rp=result;rp;rp=rp->ai_next){
		if((sfd=socket(rp->ai_family,rp->ai_socktype,rp->ai_protocol))==-1)
			continue;
		if(connect(sfd,rp->ai_addr,rp->ai_addrlen)!=-1){
			h.sfd=sfd;
			h.ffd=fdopen(sfd,mode);
			break;
		}
		close(sfd);
	}
	if(!rp){
		fprintf(stderr,"Cannot connect to: %s\n",path);
		close_pipe();
		return NULL;
	}
	freeaddrinfo(result);

	h.print_meta=1;
	if(stream_hello(filename)){
		plugin_close(NULL);
		return NULL;
	}
	free(filename);

	return h.rfd;
}
Пример #6
0
int main(int argc, char** argv) {

  int fd; /* fifo pipe fd */
  int i;
  int num_reported;
  pid_t pids[NUM_CHILDREN]; /* array of child pids */ 

  /* 
   * open up our pipe for status messages from child processes
   */ 
  if( (fd = open_pipe(FIFO_NAME)) < 0) {
    exit(-1);
  }
  
   /*
   * start up the children, and hang on to the pids
   */
  for (i = 0; i < NUM_CHILDREN; ++i) {
    pid_t pid = fork();
    pids[i] = pid;

    if(pid == -1) {
      perror("Error forking child process");
      exit(-1);
    }
    else if(pids[i] == 0) {
      run_child();
    }
  }

  /*
   * wait for the child processes to complete their task
   */
  if(await_children(pids, NUM_CHILDREN) != NUM_CHILDREN) {
    fprintf(stderr, "Child count doesn't match number forked\n");
  }

  /*
   * read the results from the pipe
   */

  num_reported = read_and_print_results(fd, pids, NUM_CHILDREN);
  if(num_reported != NUM_CHILDREN) {
    fprintf(stderr, "Not all children reported results\n");
  }

  /* done with the pipe. close and unlink it. */
  close(fd);
  unlink(FIFO_NAME);

  return 0;
}
Пример #7
0
Файл: ji.c Проект: placek/ji
static void
handle_contact_input(struct xmpp *xmpp, struct contact *u)
{
  static char buf[PIPE_BUF];

  if (read_line(u->fd, sizeof(buf), buf) == -1) {
    close(u->fd);
    u->fd = open_pipe(u->jid);
    if (u->fd < 0)
      rm_contact(u);
  } else
    do_contact_input_string(xmpp, u, buf);
}
Пример #8
0
ucci_comm_enum boot_line()
{
    char line_str[LINE_INPUT_MAX_CHAR];

    open_pipe();

    while (!line_input(line_str)) {
        idle();
    }

    if (strcmp(line_str, "ucci") == 0) {
        return UCCI_COMM_UCCI;
    } else {
        return UCCI_COMM_NONE;
    }
}
// Complete the operation:
//   - open the pipe to the client
//   - write the operation result (a jint)
//   - write the operation output (the result stream)
//
void Win32AttachOperation::complete(jint result, bufferedStream* result_stream) {
  JavaThread* thread = JavaThread::current();
  ThreadBlockInVM tbivm(thread);

  thread->set_suspend_equivalent();
  // cleared by handle_special_suspend_equivalent_condition() or
  // java_suspend_self() via check_and_wait_while_suspended()

  HANDLE hPipe = open_pipe();
  if (hPipe != INVALID_HANDLE_VALUE) {
    BOOL fSuccess;

    char msg[32];
    _snprintf(msg, sizeof(msg), "%d\n", result);
    msg[sizeof(msg) - 1] = '\0';

    fSuccess = write_pipe(hPipe, msg, (int)strlen(msg));
    if (fSuccess) {
      write_pipe(hPipe, (char*) result_stream->base(), (int)(result_stream->size()));
    }

    // Need to flush buffers
    FlushFileBuffers(hPipe);
    CloseHandle(hPipe);
  }

  DWORD res = ::WaitForSingleObject(Win32AttachListener::mutex(), INFINITE);
  if (res == WAIT_OBJECT_0) {

    // put the operation back on the available list
    set_next(Win32AttachListener::available());
    Win32AttachListener::set_available(this);

    ::ReleaseMutex(Win32AttachListener::mutex());
  }

  // were we externally suspended while we were waiting?
  thread->check_and_wait_while_suspended();
}
Пример #10
0
Файл: ji.c Проект: placek/ji
static struct contact *
add_contact(int njid, const char *jid)
{
  struct contact *u;

  find_contact(u, njid, jid);
  if (u)
    return u;

  u = calloc(1, sizeof(struct contact));
  if (!u)
    return 0;

  snprintf(u->jid, sizeof(u->jid), "%.*s", njid, jid);
  u->fd = open_pipe(u->jid);
  u->next = contacts;
  u->type = "chat";
  snprintf(u->show, sizeof(u->show), "%s", STR_OFFLINE);
  u->status[0] = 0;
  contacts = u;

  return u;
}
Пример #11
0
int main(int argc, char **argv) {

    char *x;
    const char *keydir = 0;
    long long i;
    struct pollfd p[6];
    struct pollfd *q;
    struct pollfd *watch0;
    struct pollfd *watch1;
    struct pollfd *watchtochild;
    struct pollfd *watchfromchild1;
    struct pollfd *watchfromchild2;
    struct pollfd *watchselfpipe;
    int exitsignal, exitcode;

    signal(SIGPIPE, SIG_IGN);
    signal(SIGALRM, timeout);

    log_init(0, "tinysshd", 0, 0);

    if (argc < 2) die_usage(USAGE);
    if (!argv[0]) die_usage(USAGE);
    for (;;) {
        if (!argv[1]) break;
        if (argv[1][0] != '-') break;
        x = *++argv;
        if (x[0] == '-' && x[1] == 0) break;
        if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
        while (*++x) {
            if (*x == 'q') { flagverbose = 0; continue; }
            if (*x == 'Q') { flagverbose = 1; continue; }
            if (*x == 'v') { if (flagverbose >= 2) flagverbose = 3; else flagverbose = 2; continue; }
            if (*x == 'o') { cryptotypeselected |= sshcrypto_TYPEOLDCRYPTO; continue; }
            if (*x == 'O') { cryptotypeselected &= ~sshcrypto_TYPEOLDCRYPTO; continue; }
            if (*x == 's') { cryptotypeselected |= sshcrypto_TYPENEWCRYPTO; continue; }
            if (*x == 'S') { cryptotypeselected &= ~sshcrypto_TYPENEWCRYPTO; continue; }
            if (*x == 'p') { cryptotypeselected |= sshcrypto_TYPEPQCRYPTO; continue; }
            if (*x == 'P') { cryptotypeselected &= ~sshcrypto_TYPEPQCRYPTO; continue; }
            if (*x == 'l') { flaglogger = 1; continue; }
            if (*x == 'L') { flaglogger = 0; continue; }
            if (*x == 'x') {
                if (x[1]) { channel_subsystem_add(x + 1); break; }
                if (argv[1]) { channel_subsystem_add(*++argv); break; }
            }

            die_usage(USAGE);
        }
    }
    keydir = *++argv; if (!keydir) die_usage(USAGE);

    log_init(flagverbose, "tinysshd", 1, flaglogger);

    connectioninfo(channel.localip, channel.localport, channel.remoteip, channel.remoteport);
    log_i4("connection from ", channel.remoteip, ":", channel.remoteport);

    channel_subsystem_log();

    global_init();

    blocking_disable(0);
    blocking_disable(1);
    blocking_disable(2);

    /* get server longterm keys */
    fdwd = open_cwd();
    if (fdwd == -1) die_fatal("unable to open current directory", 0, 0);
    if (chdir(keydir) == -1) die_fatal("unable to chdir to", keydir, 0);

    for (i = 0; sshcrypto_keys[i].name; ++i) sshcrypto_keys[i].sign_flagserver |= sshcrypto_kexs[i].cryptotype & cryptotypeselected;
    for (i = 0; sshcrypto_keys[i].name; ++i) sshcrypto_keys[i].sign_flagclient |= sshcrypto_kexs[i].cryptotype & cryptotypeselected;
    for (i = 0; sshcrypto_kexs[i].name; ++i) sshcrypto_kexs[i].flagenabled |= sshcrypto_kexs[i].cryptotype & cryptotypeselected;
    for (i = 0; sshcrypto_ciphers[i].name; ++i) sshcrypto_ciphers[i].flagenabled |= sshcrypto_ciphers[i].cryptotype & cryptotypeselected;

    /* read public keys */
    for (i = 0; sshcrypto_keys[i].name; ++i) {
        if (!sshcrypto_keys[i].sign_flagserver) continue;
        if (load(sshcrypto_keys[i].sign_publickeyfilename, sshcrypto_keys[i].sign_publickey, sshcrypto_keys[i].sign_publickeybytes) == -1) {
            sshcrypto_keys[i].sign_flagserver = 0;
            if (errno == ENOENT) continue;
            die_fatal("unable to read public key from file", keydir, sshcrypto_keys[i].sign_publickeyfilename);
        }
    }

    if (fchdir(fdwd) == -1) die_fatal("unable to change directory to working directory", 0, 0);
    close(fdwd);

    /* set timeout */
    alarm(60);

    /* send and receive hello */
    if (!packet_hello_send()) die_fatal("unable to send hello-string", 0, 0);
    if (!packet_hello_receive()) die_fatal("unable to receive hello-string", 0, 0);

    /* send and receive kex */
    if (!packet_kex_send()) die_fatal("unable to send kex-message", 0, 0);
    if (!packet_kex_receive()) die_fatal("unable to receive kex-message", 0, 0);

rekeying:
    /* rekeying */
    alarm(60);
    if (packet.flagrekeying == 1) {
        buf_purge(&packet.kexrecv);
        buf_put(&packet.kexrecv, b1.buf, b1.len);
        if (!packet_kex_send()) die_fatal("unable to send kex-message", 0, 0);
    }

    /* send and receive kexdh */
    if (!packet_kexdh(keydir, &b1, &b2)) die_fatal("unable to subprocess kexdh", 0, 0);

    if (packet.flagkeys) log_d1("rekeying: done");
    packet.flagkeys = 1;

    /* note: comunication is encrypted */

    /* authentication + authorization */
    if (packet.flagauthorized == 0) {
        if (!packet_auth(&b1, &b2)) die_fatal("authentication failed", 0, 0);
        packet.flagauthorized = 1;
    }

    /* note: user is authenticated and authorized */
    alarm(3600);

    /* main loop */
    for (;;) {
        if (channel_iseof())
            if (!packet.sendbuf.len)
                if (packet.flagchanneleofreceived)
                    break;

        watch0 = watch1 = 0;
        watchtochild = watchfromchild1 = watchfromchild2 = 0;
        watchselfpipe = 0;

        q = p;

        if (packet_sendisready()) { watch1 = q; q->fd = 1; q->events = POLLOUT; ++q; }
        if (packet_recvisready()) { watch0 = q; q->fd = 0; q->events = POLLIN;  ++q; }

        if (channel_writeisready()) { watchtochild = q; q->fd = channel_getfd0(); q->events = POLLOUT; ++q; }
        if (channel_readisready() && packet_putisready()) { watchfromchild1 = q; q->fd = channel_getfd1(); q->events = POLLIN; ++q; }
        if (channel_extendedreadisready() && packet_putisready()) { watchfromchild2 = q; q->fd = channel_getfd2(); q->events = POLLIN; ++q; }

        if (selfpipe[0] != -1) { watchselfpipe = q; q->fd = selfpipe[0]; q->events = POLLIN; ++q; }

        if (poll(p, q - p, 60000) < 0) {
            watch0 = watch1 = 0;
            watchtochild = watchfromchild1 = watchfromchild2 = 0;
            watchselfpipe = 0;
        }

        else {
            if (watch0) if (!watch0->revents) watch0 = 0;
            if (watch1) if (!watch1->revents) watch1 = 0;
            if (watchfromchild1) if (!watchfromchild1->revents) watchfromchild1 = 0;
            if (watchfromchild2) if (!watchfromchild2->revents) watchfromchild2 = 0;
            if (watchtochild) if (!watchtochild->revents) watchtochild = 0;
            if (watchselfpipe) if (!watchselfpipe->revents) watchselfpipe = 0;
        }

        if (watchtochild) {

            /* write data to child */
            if (!channel_write()) die_fatal("unable to write data to child", 0, 0);

            /* try to adjust window */
            if (!packet_channel_send_windowadjust(&b1)) die_fatal("unable to send data to network", 0, 0);
        }

        /* read data from child */
        if (watchfromchild1) packet_channel_send_data(&b2);
        if (watchfromchild2) packet_channel_send_extendeddata(&b2);

        /* check child */
        if (channel_iseof()) {
            if (selfpipe[0] == -1) if (open_pipe(selfpipe) == -1) die_fatal("unable to open pipe", 0, 0);
            signal(SIGCHLD, trigger);
            if (channel_waitnohang(&exitsignal, &exitcode)) {
                packet_channel_send_eof(&b2);
                if (!packet_channel_send_close(&b2, exitsignal, exitcode)) die_fatal("unable to close channel", 0, 0);
            }
        }

        /* send data to network */
        if (watch1) if (!packet_send()) die_fatal("unable to send data to network", 0, 0);

        /* receive data from network */
        if (watch0) {
            alarm(3600); /* refresh timeout */
            if (!packet_recv()) {
                if (channel_iseof()) break; /* XXX */
                die_fatal("unable to receive data from network", 0, 0);
            }
        }

        /* process packets */
        for (;;) {

            if (!packet_get(&b1, 0)) {
                if (!errno) break;
                die_fatal("unable to get packets from network", 0, 0);
            }
            if (b1.len < 1) break; /* XXX */

            switch (b1.buf[0]) {
                case SSH_MSG_CHANNEL_OPEN:
                    if (!packet_channel_open(&b1, &b2)) die_fatal("unable to open channel", 0, 0);
                    break;
                case SSH_MSG_CHANNEL_REQUEST:
                    if (!packet_channel_request(&b1, &b2)) die_fatal("unable to handle channel-request", 0, 0);
                    break;
                case SSH_MSG_CHANNEL_DATA:
                    if (!packet_channel_recv_data(&b1)) die_fatal("unable to handle channel-data", 0, 0);
                    break;
                case SSH_MSG_CHANNEL_EXTENDED_DATA:
                    if (!packet_channel_recv_extendeddata(&b1)) die_fatal("unable to handle channel-extended-data", 0, 0);
                    break;
                case SSH_MSG_CHANNEL_WINDOW_ADJUST:
                    if (!packet_channel_recv_windowadjust(&b1)) die_fatal("unable to handle channel-window-adjust", 0, 0);
                    break;
                case SSH_MSG_CHANNEL_EOF:
                    if (!packet_channel_recv_eof(&b1)) die_fatal("unable to handle channel-eof", 0, 0);
                    break;
                case SSH_MSG_CHANNEL_CLOSE:
                    if (!packet_channel_recv_close(&b1)) die_fatal("unable to handle channel-close", 0, 0);
                    break;
                case SSH_MSG_KEXINIT:
                    goto rekeying;
                default:
                    if (!packet_unimplemented(&b1)) die_fatal("unable to send SSH_MSG_UNIMPLEMENTED message", 0, 0);
            }
        }
    }

    log_i1("finished");
    global_die(0); return 111;
}
Пример #12
0
int main(int argc,char **argv)
{
  long long pos;
  long long len;
  long long u;
  long long r;
  long long i;
  long long k;
  long long recent;
  long long nextaction;
  long long timeout;
  struct pollfd *q;
  struct pollfd *watch8;
  struct pollfd *watchtochild;
  struct pollfd *watchfromchild;

  signal(SIGPIPE,SIG_IGN);

  if (!argv[0]) die_usage(0);
  for (;;) {
    char *x;
    if (!argv[1]) break;
    if (argv[1][0] != '-') break;
    x = *++argv;
    if (x[0] == '-' && x[1] == 0) break;
    if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
    while (*++x) {
      if (*x == 'q') { flagverbose = 0; continue; }
      if (*x == 'Q') { flagverbose = 1; continue; }
      if (*x == 'v') { if (flagverbose == 2) flagverbose = 3; else flagverbose = 2; continue; }
      if (*x == 'c') { flagserver = 0; wantping = 2; continue; }
      if (*x == 'C') { flagserver = 0; wantping = 1; continue; }
      if (*x == 's') { flagserver = 1; wantping = 0; continue; }
      die_usage(0);
    }
  }
  if (!*++argv) die_usage("missing prog");

  for (;;) {
    r = open_read("/dev/null");
    if (r == -1) die_fatal("unable to open /dev/null",0,0);
    if (r > 9) { close(r); break; }
  }

  if (open_pipe(tochild) == -1) die_fatal("unable to create pipe",0,0);
  if (open_pipe(fromchild) == -1) die_fatal("unable to create pipe",0,0);

  blocking_enable(tochild[0]);
  blocking_enable(fromchild[1]);

  child = fork();
  if (child == -1) die_fatal("unable to fork",0,0);
  if (child == 0) {
    close(8);
    close(9);
    if (flagserver) {
      close(0);
      if (dup(tochild[0]) != 0) die_fatal("unable to dup",0,0);
      close(1);
      if (dup(fromchild[1]) != 1) die_fatal("unable to dup",0,0);
    } else {
      close(6);
      if (dup(tochild[0]) != 6) die_fatal("unable to dup",0,0);
      close(7);
      if (dup(fromchild[1]) != 7) die_fatal("unable to dup",0,0);
    }
    signal(SIGPIPE,SIG_DFL);
    execvp(*argv,argv);
    die_fatal("unable to run",*argv,0);
  }

  close(tochild[0]);
  close(fromchild[1]);

  recent = nanoseconds();
  lastspeedadjustment = recent;
  if (flagserver) maxblocklen = 1024;

  for (;;) {
    if (sendeofacked)
      if (receivewritten == receivetotalbytes)
        if (receiveeof)
          if (tochild[1] < 0)
	    break; /* XXX: to re-ack should enter a TIME-WAIT state here */

    q = p;

    watch8 = q;
    if (watch8) { q->fd = 8; q->events = POLLIN; ++q; }

    watchtochild = q;
    if (tochild[1] < 0) watchtochild = 0;
    if (receivewritten >= receivebytes) watchtochild = 0;
    if (watchtochild) { q->fd = tochild[1]; q->events = POLLOUT; ++q; }

    watchfromchild = q;
    if (sendeof) watchfromchild = 0;
    if (sendbytes + 4096 > sizeof sendbuf) watchfromchild = 0;
    if (watchfromchild) { q->fd = fromchild[0]; q->events = POLLIN; ++q; }

    nextaction = recent + 60000000000LL;
    if (wantping == 1) nextaction = recent + 1000000000;
    if (wantping == 2) nextaction = 0;
    if (blocknum < OUTGOING)
      if (!(sendeof ? sendeofprocessed : sendprocessed >= sendbytes))
        if (nextaction > lastblocktime + nsecperblock) nextaction = lastblocktime + nsecperblock;
    if (earliestblocktime) {
      long long nextretry = earliestblocktime + rtt_timeout;
      if (nextretry < lastblocktime + nsecperblock) nextretry = lastblocktime + nsecperblock;
      if (nextretry < nextaction) nextaction = nextretry;
    }

    if (messagenum)
      if (!watchtochild)
        nextaction = 0;

    if (nextaction <= recent)
      timeout = 0;
    else
      timeout = (nextaction - recent) / 1000000 + 1;

    /* XXX */
    if (childdied) timeout = 10;
    pollret = poll(p,q - p,timeout);
    if (pollret < 0) {
      watch8 = 0;
      watchtochild = 0;
      watchfromchild = 0;
    } else {
      if (watch8) if (!watch8->revents) watch8 = 0;
      if (watchtochild) if (!watchtochild->revents) watchtochild = 0;
      if (watchfromchild) if (!watchfromchild->revents) watchfromchild = 0;
    }

    /* XXX */
    if (childdied && !pollret) {
        if (childdied++ > 999) goto finish;
    }

    /* XXX: keepalives */

    do { /* try receiving data from child: */
      if (!watchfromchild) break;
      if (sendeof) break;
      if (sendbytes + 4096 > sizeof sendbuf) break;

      pos = (sendacked & (sizeof sendbuf - 1)) + sendbytes;
      if (pos < sizeof sendbuf) {
        r = read(fromchild[0],sendbuf + pos,sizeof sendbuf - pos);
      } else {
        r = read(fromchild[0],sendbuf + pos - sizeof sendbuf,sizeof sendbuf - sendbytes);
      }
      if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break;
      if (r < 0) { sendeof = 4096; break; }
      if (r == 0) { sendeof = 2048; break; }
      sendbytes += r;
      if (sendbytes >= 1152921504606846976LL) die_internalerror();
    } while(0);

    recent = nanoseconds();

    do { /* try re-sending an old block: */
      if (recent < lastblocktime + nsecperblock) break;
      if (earliestblocktime == 0) break;
      if (recent < earliestblocktime + rtt_timeout) break;

      for (i = 0;i < blocknum;++i) {
	pos = (blockfirst + i) & (OUTGOING - 1);
        if (blocktime[pos] == earliestblocktime) {
	  if (recent > lastpanic + 4 * rtt_timeout) {
	    nsecperblock *= 2;
	    lastpanic = recent;
	    lastedge = recent;
	  }
	  goto sendblock;
        }
      }
    } while(0);

    do { /* try sending a new block: */
      if (recent < lastblocktime + nsecperblock) break;
      if (blocknum >= OUTGOING) break;
      if (!wantping)
        if (sendeof ? sendeofprocessed : sendprocessed >= sendbytes) break;
      /* XXX: if any Nagle-type processing is desired, do it here */

      pos = (blockfirst + blocknum) & (OUTGOING - 1);
      ++blocknum;
      blockpos[pos] = sendacked + sendprocessed;
      blocklen[pos] = sendbytes - sendprocessed;
      if (blocklen[pos] > maxblocklen) blocklen[pos] = maxblocklen;
      if ((blockpos[pos] & (sizeof sendbuf - 1)) + blocklen[pos] > sizeof sendbuf)
        blocklen[pos] = sizeof sendbuf - (blockpos[pos] & (sizeof sendbuf - 1));
	/* XXX: or could have the full block in post-buffer space */
      sendprocessed += blocklen[pos];
      blockeof[pos] = 0;
      if (sendprocessed == sendbytes) {
        blockeof[pos] = sendeof;
	if (sendeof) sendeofprocessed = 1;
      }
      blocktransmissions[pos] = 0;

      sendblock:

      blocktransmissions[pos] += 1;
      blocktime[pos] = recent;
      blockid[pos] = nextmessageid;
      if (!++nextmessageid) ++nextmessageid;

      /* constraints: u multiple of 16; u >= 16; u <= 1088; u >= 48 + blocklen[pos] */
      u = 64 + blocklen[pos];
      if (u <= 192) u = 192;
      else if (u <= 320) u = 320;
      else if (u <= 576) u = 576;
      else if (u <= 1088) u = 1088;
      else die_internalerror();
      if (blocklen[pos] < 0 || blocklen[pos] > 1024) die_internalerror();

      byte_zero(buf + 8,u);
      buf[7] = u / 16;
      uint32_pack(buf + 8,blockid[pos]);
      /* XXX: include any acknowledgments that have piled up */
      uint16_pack(buf + 46,blockeof[pos] | (crypto_uint16) blocklen[pos]);
      uint64_pack(buf + 48,blockpos[pos]);
      byte_copy(buf + 8 + u - blocklen[pos],blocklen[pos],sendbuf + (blockpos[pos] & (sizeof sendbuf - 1)));

      if (writeall(9,buf + 7,u + 1) == -1) die_fatal("unable to write descriptor 9",0,0);
      lastblocktime = recent;
      wantping = 0;

      earliestblocktime_compute();
    } while(0);

    do { /* try receiving messages: */
      if (!watch8) break;
      r = read(8,buf,sizeof buf);
      if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break;
      if (r == 0) die_badmessage();
      if (r < 0) die_fatal("unable to read from file descriptor 8",0,0);
      for (k = 0;k < r;++k) {
        messagetodo[messagetodolen++] = buf[k];
	u = 16 * (unsigned long long) messagetodo[0];
	if (u < 16) die_badmessage();
	if (u > 1088) die_badmessage();
	if (messagetodolen == 1 + u) {
	  if (messagenum < INCOMING) {
	    pos = (messagefirst + messagenum) & (INCOMING - 1);
	    messagelen[pos] = messagetodo[0];
	    byte_copy(message[pos],u,messagetodo + 1);
	    ++messagenum;
	  } else {
	    ; /* drop tail */
	  }
	  messagetodolen = 0;
	}
      }
    } while(0);

    do { /* try processing a message: */
      if (!messagenum) break;
      if (tochild[1] >= 0 && receivewritten < receivebytes) break;

      maxblocklen = 1024;

      pos = messagefirst & (INCOMING - 1);
      len = 16 * (unsigned long long) messagelen[pos];
      do { /* handle this message if it's comprehensible: */
	unsigned long long D;
	unsigned long long SF;
	unsigned long long startbyte;
	unsigned long long stopbyte;
	crypto_uint32 id;
	long long i;

        if (len < 48) break;
        if (len > 1088) break;

	id = uint32_unpack(message[pos] + 4);
	for (i = 0;i < blocknum;++i) {
	  k = (blockfirst + i) & (OUTGOING - 1);
	  if (blockid[k] == id) {
	    rtt = recent - blocktime[k];
	    if (!rtt_average) {
	      nsecperblock = rtt;
	      rtt_average = rtt;
	      rtt_deviation = rtt / 2;
	      rtt_highwater = rtt;
	      rtt_lowwater = rtt;
	    }

	    /* Jacobson's retransmission timeout calculation: */
	    rtt_delta = rtt - rtt_average;
	    rtt_average += rtt_delta / 8;
	    if (rtt_delta < 0) rtt_delta = -rtt_delta;
	    rtt_delta -= rtt_deviation;
	    rtt_deviation += rtt_delta / 4;
	    rtt_timeout = rtt_average + 4 * rtt_deviation;
	    /* adjust for delayed acks with anti-spiking: */
	    rtt_timeout += 8 * nsecperblock;

	    /* recognizing top and bottom of congestion cycle: */
	    rtt_delta = rtt - rtt_highwater;
	    rtt_highwater += rtt_delta / 1024;
	    rtt_delta = rtt - rtt_lowwater;
	    if (rtt_delta > 0) rtt_lowwater += rtt_delta / 8192;
	    else rtt_lowwater += rtt_delta / 256;

	    if (rtt_average > rtt_highwater + 5000000) rtt_seenrecenthigh = 1;
	    else if (rtt_average < rtt_lowwater) rtt_seenrecentlow = 1;

	    if (recent >= lastspeedadjustment + 16 * nsecperblock) {
	      if (recent - lastspeedadjustment > 10000000000LL) {
	        nsecperblock = 1000000000; /* slow restart */
		nsecperblock += randommod(nsecperblock / 8);
	      }

	      lastspeedadjustment = recent;

	      if (nsecperblock >= 131072) {
	        /* additive increase: adjust 1/N by a constant c */
	        /* rtt-fair additive increase: adjust 1/N by a constant c every nanosecond */
	        /* approximation: adjust 1/N by cN every N nanoseconds */
	        /* i.e., N <- 1/(1/N + cN) = N/(1 + cN^2) every N nanoseconds */
	        if (nsecperblock < 16777216) {
		  /* N/(1+cN^2) approx N - cN^3 */
		  u = nsecperblock / 131072;
	          nsecperblock -= u * u * u;
	        } else {
	          double d = nsecperblock;
	          nsecperblock = d/(1 + d*d / 2251799813685248.0);
	        }
	      }

	      if (rtt_phase == 0) {
	        if (rtt_seenolderhigh) {
		  rtt_phase = 1;
		  lastedge = recent;
	          nsecperblock += randommod(nsecperblock / 4);
		}
	      } else {
	        if (rtt_seenolderlow) {
		  rtt_phase = 0;
	        }
	      }

	      rtt_seenolderhigh = rtt_seenrecenthigh;
	      rtt_seenolderlow = rtt_seenrecentlow;
	      rtt_seenrecenthigh = 0;
	      rtt_seenrecentlow = 0;
	    }

	    do {
	      if (recent - lastedge < 60000000000LL) {
	        if (recent < lastdoubling + 4 * nsecperblock + 64 * rtt_timeout + 5000000000LL) break;
	      } else {
	        if (recent < lastdoubling + 4 * nsecperblock + 2 * rtt_timeout) break;
	      }
	      if (nsecperblock <= 65535) break;

              nsecperblock /= 2;
	      lastdoubling = recent;
	      if (lastedge) lastedge = recent;
	    } while(0);
	  }
	}

	stopbyte = uint64_unpack(message[pos] + 8);
	acknowledged(0,stopbyte);
	startbyte = stopbyte + (unsigned long long) uint32_unpack(message[pos] + 16);
	stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 20);
	acknowledged(startbyte,stopbyte);
	startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 22);
	stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 24);
	acknowledged(startbyte,stopbyte);
	startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 26);
	stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 28);
	acknowledged(startbyte,stopbyte);
	startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 30);
	stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 32);
	acknowledged(startbyte,stopbyte);
	startbyte = stopbyte + (unsigned long long) uint16_unpack(message[pos] + 34);
	stopbyte = startbyte + (unsigned long long) uint16_unpack(message[pos] + 36);
	acknowledged(startbyte,stopbyte);

	D = uint16_unpack(message[pos] + 38);
	SF = D & (2048 + 4096);
	D -= SF;
	if (D > 1024) break;
	if (48 + D > len) break;

	startbyte = uint64_unpack(message[pos] + 40);
	stopbyte = startbyte + D;

	if (stopbyte > receivewritten + sizeof receivebuf) {
	  break;
	  /* of course, flow control would avoid this case */
	}

	if (SF) {
	  receiveeof = SF;
	  receivetotalbytes = stopbyte;
	}

	for (k = 0;k < D;++k) {
	  unsigned char ch = message[pos][len - D + k];
	  unsigned long long where = startbyte + k;
	  if (where >= receivewritten && where < receivewritten + sizeof receivebuf) {
	    receivevalid[where & (sizeof receivebuf - 1)] = 1;
	    receivebuf[where & (sizeof receivebuf - 1)] = ch;
	  }
	}
	for (;;) {
	  if (receivebytes >= receivewritten + sizeof receivebuf) break;
	  if (!receivevalid[receivebytes & (sizeof receivebuf - 1)]) break;
	  ++receivebytes;
	}

	if (!uint32_unpack(message[pos])) break; /* never acknowledge a pure acknowledgment */

	/* XXX: delay acknowledgments */
	u = 192;
        byte_zero(buf + 8,u);
        buf[7] = u / 16;
	byte_copy(buf + 12,4,message[pos]);
	if (receiveeof && receivebytes == receivetotalbytes) {
	  uint64_pack(buf + 16,receivebytes + 1);
	} else
	  uint64_pack(buf + 16,receivebytes);
	/* XXX: incorporate selective acknowledgments */
  
        if (writeall(9,buf + 7,u + 1) == -1) die_fatal("unable to write descriptor 9",0,0);
      } while(0);

      ++messagefirst;
      --messagenum;
    } while(0);

    do { /* try sending data to child: */
      if (!watchtochild) break;
      if (tochild[1] < 0) { receivewritten = receivebytes; break; }
      if (receivewritten >= receivebytes) break;

      pos = receivewritten & (sizeof receivebuf - 1);
      len = receivebytes - receivewritten;
      if (pos + len > sizeof receivebuf) len = sizeof receivebuf - pos;
      r = write(tochild[1],receivebuf + pos,len);
      if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break;
      if (r <= 0) {
        close(tochild[1]);
        tochild[1] = -1;
	break;
      }
      byte_zero(receivevalid + pos,r);
      receivewritten += r;
    } while(0);

    do { /* try closing pipe to child: */
      if (!receiveeof) break;
      if (receivewritten < receivetotalbytes) break;
      if (tochild[1] < 0) break;

      if (receiveeof == 4096)
        ; /* XXX: UNIX doesn't provide a way to signal an error through a pipe */
      close(tochild[1]);
      tochild[1] = -1;
    } while(0);

    /* XXX */
    if (!childdied){
        if (waitpid(child,&childstatus, WNOHANG) > 0) {
          close(tochild[1]);
          tochild[1] = -1;
          childdied = 1;
        }
    }
  }

  if (!childdied) {
    do {
      r = waitpid(child,&childstatus,0);
    } while (r == -1 && errno == EINTR);
  }

finish:

  if (!WIFEXITED(childstatus)) { errno = 0; die_fatal("process killed by signal",0,0); }
  return WEXITSTATUS(childstatus);
}
Пример #13
0
irep_pipet::irep_pipet(const bool auto_close) :
    read_closed(false), write_closed(false), close_on_destuction(auto_close)
{
    open_pipe(fd);
}
Пример #14
0
irep_pipet::irep_pipet() :
    read_closed(false), write_closed(false), close_on_destuction(false)
{
    open_pipe(fd);
}
Пример #15
0
int
run_main (int argc, ACE_TCHAR *argv[])
{
    parse_args (argc, argv);

    if (child_process)
    {
        ACE_APPEND_LOG (ACE_TEXT("Pipe_Test-children"));
        ACE_Pipe a, b, c, d, e;

        open_pipe (a, "a");
        open_pipe (b, "b");
        open_pipe (c, "c");
        open_pipe (d, "d");
        open_pipe (e, "e");

        ACE_END_LOG;
    }
    else
    {
        ACE_START_TEST (ACE_TEXT("Pipe_Test"));
        ACE_INIT_LOG (ACE_TEXT("Pipe_Test-children"));

#  if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
        const ACE_TCHAR *cmdline_fmt = ACE_TEXT ("%s -c%s");
#  else
        const ACE_TCHAR *cmdline_fmt = ACE_TEXT ("%ls -c%ls");
#  endif /* ACE_WIN32 || !ACE_USES_WCHAR */
        ACE_Process_Options options;
        options.command_line (cmdline_fmt,
                              argc > 0 ? argv[0] : ACE_TEXT ("Pipe_Test"),
                              close_pipe == 0 ? ACE_TEXT (" -d") : ACE_TEXT (""));

        ACE_exitcode status = 0;

        for (int i = 0; i < ::iterations; i++)
        {
            ACE_Process server;

            if (server.spawn (options) == -1)
            {
                ACE_ERROR_RETURN ((LM_ERROR,
                                   ACE_TEXT ("%p\n"),
                                   ACE_TEXT ("spawn failed")),
                                  -1);
            }
            else
            {
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("Server forked with pid = %d.\n"),
                            server.getpid ()));
            }

            // Wait for the process we just created to exit.
            server.wait (&status);

            // Check if child exited without error.
            if (WIFEXITED (status) != 0
                    && WEXITSTATUS (status) != 0)
            {
                ACE_ERROR ((LM_ERROR,
                            ACE_TEXT ("Child of server %d finished with error ")
                            ACE_TEXT ("exit status %d\n"),
                            server.getpid (),
                            WEXITSTATUS (status)));

                ACE_END_TEST;

                ACE_OS::exit (WEXITSTATUS (status));
            }

            ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Server %d finished\n"),
                        server.getpid ()));
        }
        ACE_END_TEST;
    }

    return 0;
}
Пример #16
0
int main(int argc,char *argv[]){
    I=0;
    int argv_index=1;
    for(argv_index=1;argv_index<argc;argv_index++){
	if(argv[argv_index][0]=='-'){
		if(strlen(argv[argv_index])==2){
			if((argv[argv_index][1])=='g'){
				gravity=atof(argv[argv_index+1]);
			}
			else if((argv[argv_index][1])=='t'){
				thrust=atof(argv[argv_index+1]);
			}
			else if((argv[argv_index][1])=='f'){
				landscape=fopen(argv[argv_index+1],"r");
			}
                        else if((argv[argv_index][1])=='i'){
                                I=1;
                        }
		}
		else if(strlen(argv[argv_index])>2){
			if((argv[argv_index][1])=='g'){
				gravity=atof(argv[argv_index]+2);
			}
			else if((argv[argv_index][1])=='t'){
				thrust=atof(argv[argv_index]+2);
			}
			else if((argv[argv_index][1])=='f'){
				landscape=fopen(argv[argv_index]+2,"r");
			}
		}
	}
    }
    fuel=10;
    ship_degree=90;
    // curses set up------------------------------------------
    setup_curses();
    open_pipe(exec_name);
    move(5, 10);
    printw("Press any key to start.\n");
    printw("          (Then press arrow keys to rotate, space for thust, 'q' to quit)");
    refresh();
    int cmd = getch();
	
    nodelay(stdscr, true);
    erase();
    move(5, 0);
    printw("left arrow key rotate counter-clockwise, right clockwise, space for thust, q to quit.");
	
    //set initial location of the ship-----------------
	
    //left_up point
    ship[0].x=315;
    ship[0].y=20;
    
    //right_up point
    ship[1].x=325;
    ship[1].y=20;
    
    //left_down point
    ship[2].x=305;
    ship[2].y=50;
    
    //right_down point
    ship[3].x=335;
    ship[3].y=50;
    
    //thrust point
    ship[4].x=320;
    ship[4].y=60;

    // set all switches-----------------------------
    over=0;
    thrust_sw=0;
    //set_velocity--------------------------------------
    xV=0;yV=0;
    //draw the landscape
    draw_landscape(landscape);
    if(I==1){
        draw_fuel_rec();
    }
    //set_timer-------------------------------------
    sigemptyset(&block_mask_g);
    sigaddset(&block_mask_g, SIGALRM);
    struct sigaction handler;
    handler.sa_handler = handle_timeout;
    sigemptyset(&handler.sa_mask);
    handler.sa_flags = 0;
    if (sigaction(SIGALRM, &handler, NULL) == -1){
        exit(EXIT_FAILURE);
    }
    struct itimerval timer;
        struct timeval time_delay;
        time_delay.tv_sec = 0;
        time_delay.tv_usec = 50000;
        timer.it_interval = time_delay;
        struct timeval start;
        start.tv_sec = 0;
        start.tv_usec = 50000;
        timer.it_value = start;
    if (setitimer(ITIMER_REAL, &timer, NULL) == -1){
        exit(EXIT_FAILURE);
    }
    while(1){
        cmd = getch();
        if (cmd != ERR){
            if (cmd == KEY_LEFT){
                if(over==0){
                    blocking_signal_for_rotate(1);  //rotate left
                }
            }
            else if(cmd == KEY_RIGHT){
                if(over==0){
                    blocking_signal_for_rotate(0);  //rotate right
                }
            }
            else if(cmd == ' '){
                if(I==0){
                    thrust_sw=1;
                }
                else if(I==1){
                    if(fuel<=0){
                        move(8,10);
                        refresh();
                        printw("Empty fuel tank ! ! ! !");
                    }
                    else if(fuel>0){
                        thrust_sw=1;
                    }
                }
            }
            else if(cmd == 'q'){
                // block the signal
                sigset_t old_mask;
                if (sigprocmask(SIG_BLOCK, &block_mask_g, &old_mask) < 0){
                    exit(EXIT_FAILURE);
                }
                break;
            }
        }
    }
    if(executable!=NULL&&over==0){
        fprintf(executable,"end\n");
    }
    unset_curses();
    //-----------------------------------------------------------
    fclose(landscape);
    close_pipe();
    exit(EXIT_SUCCESS);
}
Пример #17
0
int process()
{
#define BUFSIZE 2048

	FILE *outf;
	char filename[PATH_MAX + 1];
	char analyzeline[PATH_MAX*3 + 1];
	int lineno;
	static char buf[BUFSIZE+1];

	if(open_pipe()) {
		if(childpid)
			kill(childpid, SIGTERM);
		exit(8);
	}
	while(terminate != 2) {

		while(last_logno - first_logno > no_of_segments) {
			snprintf(filename, PATH_MAX, "%s.%d", logbasename, first_logno);
			if (analyzer != NULL) {
				snprintf(analyzeline, PATH_MAX*3, "%s %s", analyzer, filename);
				system(analyzeline);
			}
			unlink(filename);
			first_logno++;
		}

		last_logno++;
		snprintf(filename, PATH_MAX, "%s.%d", logbasename, last_logno);
		outf = fopen(filename, "w");
		if(outf == NULL) {
			fprintf(stderr, "Error opening file %s : %s\n", filename, strerror(errno));
			if(childpid) {
				kill(childpid, SIGTERM);
				sleep(10);
			}
			return 9;
		}
		fnout = fileno(outf);
		lineno = 0;
		while((lineno < no_of_lines) && (terminate != 2)) {
			if(fgets(buf, BUFSIZE, paip) == NULL) {
				fclose(paip);
				fflush(outf);
				if (childpid) {
					fprintf(outf, "[scrolllog] Waiting for child (%d) to terminate\n", (int) childpid);
					fflush(outf);
					do {
						switch ((int)waitpid((pid_t) -1, &status, 0)) {
						case -1:
							if(errno == ECHILD) {

								fprintf(outf, "[scrolllog] WARNING, childpid != 0 && ECHILD !\n");
								fflush(outf);

								restart   = 1;
							}
							break;
						default:
							if (WIFEXITED(status)) {
								status = WEXITSTATUS(status);
							} else if (WIFSIGNALED(status)) {
								status = 128 + WTERMSIG(status);
							} else
								continue;
							fprintf(outf, "[scrolllog] Child exited with state %d\n", status);
							fflush(outf);
							if (status == 0) restart = 0;
							else restart = 1;
						}

						childpid  = 0;
						terminate = 1;
					} while(childpid != 0);
				}
				if(terminate == 1) {
					if(restart && (cmd != NULL)) {
						fprintf(outf, "[scrolllog] Try to restart child (child terminated with exit code <> 0)\n");
						fflush(outf);
						if(start_cmd() != 0) {
							fprintf(outf, "[scrolllog] restart of child failed\n");
							fflush(outf);
							exit(9);
						}
						terminate = 0;
					} else {
						terminate = 2;
						fprintf(outf, "[scrolllog] I terminate (after cleaning up)\n");
						fflush(outf);
						break;
					}
				}
				if(open_pipe()) {
					terminate = 2;
					fprintf(outf, "\n");
					fprintf(outf, "\n[scrolllog] ****************************************");
					fprintf(outf, "\n[scrolllog] **                                    **");
					fprintf(outf, "\n[scrolllog] ** Couldn't open/lock pipe            **");
					if(childpid) {
						fprintf(outf, "\n[scrolllog] ** scrolllog terminates and sends a   **");
						fprintf(outf, "\n[scrolllog] ** SIGTERM to its child               **");
						kill(childpid, SIGTERM);
						sleep(10);
					}
					fprintf(outf, "\n[scrolllog] **                                    **");
					fprintf(outf, "\n[scrolllog] ****************************************\n");
					fflush(outf);
					return 10;
				}

				continue;
			}
			fputs(buf, outf);
			fflush(outf);
			lineno++;
		}
		fclose(outf);

	}

	return status;
}
Пример #18
0
int main(int argc,char **argv)
{
  long long hellopackets;
  long long r;
  long long nextaction;

  signal(SIGPIPE,SIG_IGN);

  if (!argv[0]) die_usage(0);
  for (;;) {
    char *x;
    if (!argv[1]) break;
    if (argv[1][0] != '-') break;
    x = *++argv;
    if (x[0] == '-' && x[1] == 0) break;
    if (x[0] == '-' && x[1] == '-' && x[2] == 0) break;
    while (*++x) {
      if (*x == 'q') { flagverbose = 0; continue; }
      if (*x == 'Q') { flagverbose = 1; continue; }
      if (*x == 'v') { if (flagverbose == 2) flagverbose = 3; else flagverbose = 2; continue; }
      if (*x == 'c') {
        if (x[1]) { keydir = x + 1; break; }
        if (argv[1]) { keydir = *++argv; break; }
      }
      die_usage(0);
    }
  }
  if (!nameparse(servername,*++argv)) die_usage("sname must be at most 255 bytes, at most 63 bytes between dots");
  if (!hexparse(serverlongtermpk,32,*++argv)) die_usage("pk must be exactly 64 hex characters");
  if (!multiipparse(serverip,*++argv)) die_usage("ip must be a comma-separated series of IPv4 addresses");
  if (!portparse(serverport,*++argv)) die_usage("port must be an integer between 0 and 65535");
  if (!hexparse(serverextension,16,*++argv)) die_usage("ext must be exactly 32 hex characters");
  if (!*++argv) die_usage("missing prog");

  for (;;) {
    r = open_read("/dev/null");
    if (r == -1) die_fatal("unable to open /dev/null",0,0);
    if (r > 9) { close(r); break; }
  }

  if (keydir) {
    fdwd = open_cwd();
    if (fdwd == -1) die_fatal("unable to open current working directory",0,0);
    if (chdir(keydir) == -1) die_fatal("unable to change to directory",keydir,0);
    if (load("publickey",clientlongtermpk,sizeof clientlongtermpk) == -1) die_fatal("unable to read public key from",keydir,0);
    if (load(".expertsonly/secretkey",clientlongtermsk,sizeof clientlongtermsk) == -1) die_fatal("unable to read secret key from",keydir,0);
  } else {
    crypto_box_keypair(clientlongtermpk,clientlongtermsk);
  }

  crypto_box_keypair(clientshorttermpk,clientshorttermsk);
  clientshorttermnonce = randommod(281474976710656LL);
  crypto_box_beforenm(clientshortserverlong,serverlongtermpk,clientshorttermsk);
  crypto_box_beforenm(clientlongserverlong,serverlongtermpk,clientlongtermsk);

  udpfd = socket_udp();
  if (udpfd == -1) die_fatal("unable to create socket",0,0);

  for (hellopackets = 0;hellopackets < NUMIP;++hellopackets) {
    recent = nanoseconds();

    /* send a Hello packet: */

    clientextension_init();

    clientshorttermnonce_update();
    byte_copy(nonce,16,"CurveCP-client-H");
    uint64_pack(nonce + 16,clientshorttermnonce);

    byte_copy(packet,8,"QvnQ5XlH");
    byte_copy(packet + 8,16,serverextension);
    byte_copy(packet + 24,16,clientextension);
    byte_copy(packet + 40,32,clientshorttermpk);
    byte_copy(packet + 72,64,allzero);
    byte_copy(packet + 136,8,nonce + 16);
    crypto_box_afternm(text,allzero,96,nonce,clientshortserverlong);
    byte_copy(packet + 144,80,text + 16);

    socket_send(udpfd,packet,224,serverip + 4 * hellopackets,serverport);

    nextaction = recent + hellowait[hellopackets] + randommod(hellowait[hellopackets]);

    for (;;) {
      long long timeout = nextaction - recent;
      if (timeout <= 0) break;
      p[0].fd = udpfd;
      p[0].events = POLLIN;
      if (poll(p,1,timeout / 1000000 + 1) < 0) p[0].revents = 0;

      do { /* try receiving a Cookie packet: */
        if (!p[0].revents) break;
        r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport);
        if (r != 200) break;
        if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) &
              byte_isequal(packetport,2,serverport) &
              byte_isequal(packet,8,"RL3aNMXK") &
              byte_isequal(packet + 8,16,clientextension) &
              byte_isequal(packet + 24,16,serverextension)
           )) break;
        byte_copy(nonce,8,"CurveCPK");
        byte_copy(nonce + 8,16,packet + 40);
        byte_zero(text,16);
        byte_copy(text + 16,144,packet + 56);
        if (crypto_box_open_afternm(text,text,160,nonce,clientshortserverlong)) break;
        byte_copy(servershorttermpk,32,text + 32);
        byte_copy(servercookie,96,text + 64);
        byte_copy(serverip,4,serverip + 4 * hellopackets);
        goto receivedcookie;
      } while (0);

      recent = nanoseconds();
    }
  }

  errno = ETIMEDOUT; die_fatal("no response from server",0,0);

  receivedcookie:

  crypto_box_beforenm(clientshortservershort,servershorttermpk,clientshorttermsk);

  byte_copy(nonce,8,"CurveCPV");
  if (keydir) {
    if (safenonce(nonce + 8,0) == -1) die_fatal("nonce-generation disaster",0,0);
  } else {
    randombytes(nonce + 8,16);
  }

  byte_zero(text,32);
  byte_copy(text + 32,32,clientshorttermpk);
  crypto_box_afternm(text,text,64,nonce,clientlongserverlong);
  byte_copy(vouch,16,nonce + 8);
  byte_copy(vouch + 16,48,text + 16);

  /* server is responding, so start child: */

  if (open_pipe(tochild) == -1) die_fatal("unable to create pipe",0,0);
  if (open_pipe(fromchild) == -1) die_fatal("unable to create pipe",0,0);

  child = fork();
  if (child == -1) die_fatal("unable to fork",0,0);
  if (child == 0) {
    if (keydir) if (fchdir(fdwd) == -1) die_fatal("unable to chdir to original directory",0,0);
    close(8);
    if (dup(tochild[0]) != 8) die_fatal("unable to dup",0,0);
    close(9);
    if (dup(fromchild[1]) != 9) die_fatal("unable to dup",0,0);
    /* XXX: set up environment variables */
    signal(SIGPIPE,SIG_DFL);
    execvp(*argv,argv);
    die_fatal("unable to run",*argv,0);
  }

  close(fromchild[1]);
  close(tochild[0]);


  for (;;) {
    p[0].fd = udpfd;
    p[0].events = POLLIN;
    p[1].fd = fromchild[0];
    p[1].events = POLLIN;

    if (poll(p,2,-1) < 0) {
      p[0].revents = 0;
      p[1].revents = 0;
    }

    do { /* try receiving a Message packet: */
      if (!p[0].revents) break;
      r = socket_recv(udpfd,packet,sizeof packet,packetip,packetport);
      if (r < 80) break;
      if (r > 1152) break;
      if (r & 15) break;
      packetnonce = uint64_unpack(packet + 40);
      if (flagreceivedmessage && packetnonce <= receivednonce) break;
      if (!(byte_isequal(packetip,4,serverip + 4 * hellopackets) &
            byte_isequal(packetport,2,serverport) &
            byte_isequal(packet,8,"RL3aNMXM") &
            byte_isequal(packet + 8,16,clientextension) &
            byte_isequal(packet + 24,16,serverextension)
         )) break;
      byte_copy(nonce,16,"CurveCP-server-M");
      byte_copy(nonce + 16,8,packet + 40);
      byte_zero(text,16);
      byte_copy(text + 16,r - 48,packet + 48);
      if (crypto_box_open_afternm(text,text,r - 32,nonce,clientshortservershort)) break;

      if (!flagreceivedmessage) {
        flagreceivedmessage = 1;
	randombytes(clientlongtermpk,sizeof clientlongtermpk);
	randombytes(vouch,sizeof vouch);
	randombytes(servername,sizeof servername);
	randombytes(servercookie,sizeof servercookie);
      }

      receivednonce = packetnonce;
      text[31] = (r - 64) >> 4;
      /* child is responsible for reading all data immediately, so we won't block: */
      if (writeall(tochild[1],text + 31,r - 63) == -1) goto done;
    } while (0);

    do { /* try receiving data from child: */
      long long i;
      if (!p[1].revents) break;
      r = read(fromchild[0],childbuf,sizeof childbuf);
      if (r == -1) if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) break;
      if (r <= 0) goto done;
      childbuflen = r;
      for (i = 0;i < childbuflen;++i) {
	if (childmessagelen < 0) goto done;
	if (childmessagelen >= sizeof childmessage) goto done;
        childmessage[childmessagelen++] = childbuf[i];
	if (childmessage[0] & 128) goto done;
	if (childmessagelen == 1 + 16 * (unsigned long long) childmessage[0]) {
	  clientextension_init();
	  clientshorttermnonce_update();
          uint64_pack(nonce + 16,clientshorttermnonce);
	  if (flagreceivedmessage) {
	    r = childmessagelen - 1;
	    if (r < 16) goto done;
	    if (r > 1088) goto done;
            byte_copy(nonce,16,"CurveCP-client-M");
	    byte_zero(text,32);
	    byte_copy(text + 32,r,childmessage + 1);
	    crypto_box_afternm(text,text,r + 32,nonce,clientshortservershort);
	    byte_copy(packet,8,"QvnQ5XlM");
	    byte_copy(packet + 8,16,serverextension);
	    byte_copy(packet + 24,16,clientextension);
	    byte_copy(packet + 40,32,clientshorttermpk);
	    byte_copy(packet + 72,8,nonce + 16);
	    byte_copy(packet + 80,r + 16,text + 16);
            socket_send(udpfd,packet,r + 96,serverip,serverport);
	  } else {
	    r = childmessagelen - 1;
	    if (r < 16) goto done;
	    if (r > 640) goto done;
	    byte_copy(nonce,16,"CurveCP-client-I");
	    byte_zero(text,32);
	    byte_copy(text + 32,32,clientlongtermpk);
	    byte_copy(text + 64,64,vouch);
	    byte_copy(text + 128,256,servername);
	    byte_copy(text + 384,r,childmessage + 1);
	    crypto_box_afternm(text,text,r + 384,nonce,clientshortservershort);
	    byte_copy(packet,8,"QvnQ5XlI");
	    byte_copy(packet + 8,16,serverextension);
	    byte_copy(packet + 24,16,clientextension);
	    byte_copy(packet + 40,32,clientshorttermpk);
	    byte_copy(packet + 72,96,servercookie);
	    byte_copy(packet + 168,8,nonce + 16);
	    byte_copy(packet + 176,r + 368,text + 16);
            socket_send(udpfd,packet,r + 544,serverip,serverport);
	  }
	  childmessagelen = 0;
	}
      }
    } while (0);
  }


  done:

  do {
    r = waitpid(child,&childstatus,0);
  } while (r == -1 && errno == EINTR);

  if (!WIFEXITED(childstatus)) { errno = 0; die_fatal("process killed by signal",0,0); }
  return WEXITSTATUS(childstatus);
}
Пример #19
0
static int				/* O - 0 on success, 1 on error */
exec_filters(mime_type_t   *srctype,	/* I - Source type */
             cups_array_t  *filters,	/* I - Array of filters to run */
             const char    *infile,	/* I - File to filter */
	     const char    *outfile,	/* I - File to create */
	     const char    *ppdfile,	/* I - PPD file, if any */
	     const char    *printer,	/* I - Printer name */
	     const char    *user,	/* I - Username */
	     const char    *title,	/* I - Job title */
             int           num_options,	/* I - Number of filter options */
	     cups_option_t *options)	/* I - Filter options */
{
  int		i;			/* Looping var */
  const char	*argv[8],		/* Command-line arguments */
		*envp[17],		/* Environment variables */
		*temp;			/* Temporary string */
  char		*optstr,		/* Filter options */
		content_type[1024],	/* CONTENT_TYPE */
		cups_datadir[1024],	/* CUPS_DATADIR */
		cups_fontpath[1024],	/* CUPS_FONTPATH */
		cups_serverbin[1024],	/* CUPS_SERVERBIN */
		cups_serverroot[1024],	/* CUPS_SERVERROOT */
		final_content_type[1024] = "",
					/* FINAL_CONTENT_TYPE */
		lang[1024],		/* LANG */
		path[1024],		/* PATH */
		ppd[1024],		/* PPD */
		printer_info[255],	/* PRINTER_INFO env variable */
		printer_location[255],	/* PRINTER_LOCATION env variable */
		printer_name[255],	/* PRINTER env variable */
		rip_max_cache[1024],	/* RIP_MAX_CACHE */
		userenv[1024],		/* USER */
		program[1024];		/* Program to run */
  mime_filter_t	*filter,		/* Current filter */
		*next;			/* Next filter */
  int		current,		/* Current filter */
		filterfds[2][2],	/* Pipes for filters */
		pid,			/* Process ID of filter */
		status,			/* Exit status */
		retval;			/* Return value */
  cups_array_t	*pids;			/* Executed filters array */
  mime_filter_t	key;			/* Search key for filters */
  cups_lang_t	*language;		/* Current language */
  cups_dest_t	*dest;			/* Destination information */


 /*
  * Figure out the final content type...
  */

  for (filter = (mime_filter_t *)cupsArrayLast(filters);
       filter && filter->dst;
       filter = (mime_filter_t *)cupsArrayPrev(filters))
    if (strcmp(filter->dst->super, "printer"))
      break;

  if (filter && filter->dst)
  {
    const char *ptr;			/* Pointer in type name */

    if ((ptr = strchr(filter->dst->type, '/')) != NULL)
      snprintf(final_content_type, sizeof(final_content_type),
	       "FINAL_CONTENT_TYPE=%s", ptr + 1);
    else
      snprintf(final_content_type, sizeof(final_content_type),
	       "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super,
	       filter->dst->type);
  }

 /*
  * Remove NULL ("-") filters...
  */

  for (filter = (mime_filter_t *)cupsArrayFirst(filters);
       filter;
       filter = (mime_filter_t *)cupsArrayNext(filters))
    if (!strcmp(filter->filter, "-"))
      cupsArrayRemove(filters, filter);

 /*
  * Setup the filter environment and command-line...
  */

  optstr = escape_options(num_options, options);

  snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s",
           srctype->super, srctype->type);
  snprintf(cups_datadir, sizeof(cups_datadir), "CUPS_DATADIR=%s", DataDir);
  snprintf(cups_fontpath, sizeof(cups_fontpath), "CUPS_FONTPATH=%s", FontPath);
  snprintf(cups_serverbin, sizeof(cups_serverbin), "CUPS_SERVERBIN=%s",
           ServerBin);
  snprintf(cups_serverroot, sizeof(cups_serverroot), "CUPS_SERVERROOT=%s",
           ServerRoot);
  language = cupsLangDefault();
  snprintf(lang, sizeof(lang), "LANG=%s.UTF8", language->language);
  snprintf(path, sizeof(path), "PATH=%s", Path);
  if (ppdfile)
    snprintf(ppd, sizeof(ppd), "PPD=%s", ppdfile);
  else if ((temp = getenv("PPD")) != NULL)
    snprintf(ppd, sizeof(ppd), "PPD=%s", temp);
  else
#ifdef __APPLE__
  if (!access("/System/Library/Frameworks/ApplicationServices.framework/"
	      "Versions/A/Frameworks/PrintCore.framework/Versions/A/"
	      "Resources/English.lproj/Generic.ppd", 0))
    strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/"
                 "Versions/A/Frameworks/PrintCore.framework/Versions/A/"
		 "Resources/English.lproj/Generic.ppd", sizeof(ppd));
  else
    strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/"
                 "Versions/A/Frameworks/PrintCore.framework/Versions/A/"
		 "Resources/Generic.ppd", sizeof(ppd));
#else
    snprintf(ppd, sizeof(ppd), "PPD=%s/model/laserjet.ppd", DataDir);
#endif /* __APPLE__ */
  snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache);
  snprintf(userenv, sizeof(userenv), "USER=%s", user);

  if (printer &&
      (dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer, NULL)) != NULL)
  {
    if ((temp = cupsGetOption("printer-info", dest->num_options,
                              dest->options)) != NULL)
      snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", temp);
    else
      snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", printer);

    if ((temp = cupsGetOption("printer-location", dest->num_options,
                              dest->options)) != NULL)
      snprintf(printer_location, sizeof(printer_location),
               "PRINTER_LOCATION=%s", temp);
    else
      strlcpy(printer_location, "PRINTER_LOCATION=Unknown",
              sizeof(printer_location));
  }
  else
  {
    snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s",
             printer ? printer : "Unknown");
    strlcpy(printer_location, "PRINTER_LOCATION=Unknown",
            sizeof(printer_location));
  }

  snprintf(printer_name, sizeof(printer_name), "PRINTER=%s",
	   printer ? printer : "Unknown");

  argv[0] = (char *)printer;
  argv[1] = "1";
  argv[2] = user;
  argv[3] = title;
  argv[4] = cupsGetOption("copies", num_options, options);
  argv[5] = optstr;
  argv[6] = infile;
  argv[7] = NULL;

  if (!argv[4])
    argv[4] = "1";

  envp[0]  = "<CFProcessPath>";
  envp[1]  = content_type;
  envp[2]  = cups_datadir;
  envp[3]  = cups_fontpath;
  envp[4]  = cups_serverbin;
  envp[5]  = cups_serverroot;
  envp[6]  = lang;
  envp[7]  = path;
  envp[8]  = ppd;
  envp[9]  = printer_info;
  envp[10] = printer_location;
  envp[11] = printer_name;
  envp[12] = rip_max_cache;
  envp[13] = userenv;
  envp[14] = "CHARSET=utf-8";
  if (final_content_type[0])
  {
    envp[15] = final_content_type;
    envp[16] = NULL;
  }
  else
    envp[15] = NULL;

  for (i = 0; argv[i]; i ++)
    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);

  for (i = 0; envp[i]; i ++)
    fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]);

 /*
  * Execute all of the filters...
  */

  pids            = cupsArrayNew((cups_array_func_t)compare_pids, NULL);
  current         = 0;
  filterfds[0][0] = -1;
  filterfds[0][1] = -1;
  filterfds[1][0] = -1;
  filterfds[1][1] = -1;

  if (!infile)
    filterfds[0][0] = 0;

  for (filter = (mime_filter_t *)cupsArrayFirst(filters);
       filter;
       filter = next, current = 1 - current)
  {
    next = (mime_filter_t *)cupsArrayNext(filters);

    if (filter->filter[0] == '/')
      strlcpy(program, filter->filter, sizeof(program));
    else
      snprintf(program, sizeof(program), "%s/filter/%s", ServerBin,
	       filter->filter);

    if (filterfds[!current][1] > 1)
    {
      close(filterfds[1 - current][0]);
      close(filterfds[1 - current][1]);

      filterfds[1 - current][0] = -1;
      filterfds[1 - current][0] = -1;
    }

    if (next)
      open_pipe(filterfds[1 - current]);
    else if (outfile)
    {
      filterfds[1 - current][1] = open(outfile, O_CREAT | O_TRUNC | O_WRONLY,
                                       0666);

      if (filterfds[1 - current][1] < 0)
        fprintf(stderr, "ERROR: Unable to create \"%s\" - %s\n", outfile,
	        strerror(errno));
    }
    else
      filterfds[1 - current][1] = 1;

    pid = exec_filter(program, (char **)argv, (char **)envp,
                      filterfds[current][0], filterfds[1 - current][1]);

    if (pid > 0)
    {
      fprintf(stderr, "INFO: %s (PID %d) started.\n", filter->filter, pid);

      filter->cost = pid;
      cupsArrayAdd(pids, filter);
    }
    else
      break;

    argv[6] = NULL;
  }

 /*
  * Close remaining pipes...
  */

  if (filterfds[0][1] > 1)
  {
    close(filterfds[0][0]);
    close(filterfds[0][1]);
  }

  if (filterfds[1][1] > 1)
  {
    close(filterfds[1][0]);
    close(filterfds[1][1]);
  }

 /*
  * Wait for the children to exit...
  */

  retval = 0;

  while (cupsArrayCount(pids) > 0)
  {
    if ((pid = wait(&status)) < 0)
      continue;

    key.cost = pid;
    if ((filter = (mime_filter_t *)cupsArrayFind(pids, &key)) != NULL)
    {
      cupsArrayRemove(pids, filter);

      if (status)
      {
	if (WIFEXITED(status))
	  fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d\n",
		  filter->filter, pid, WEXITSTATUS(status));
	else
	  fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d\n",
		  filter->filter, pid, WTERMSIG(status));

        retval = 1;
      }
      else
        fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n",
	        filter->filter, pid);
    }
  }

  cupsArrayDelete(pids);

  return (retval);
}
Пример #20
0
static int				/* O - 0 on success, 1 on error */
exec_filters(cups_array_t  *filters,	/* I - Array of filters to run */
	     char	   **argv)	/* I - Filter options */
{
  int		i;			/* Looping var */
  char		program[1024];		/* Program to run */
  char		*filter,		/* Current filter */
		*next;			/* Next filter */
  int		current,		/* Current filter */
		filterfds[2][2],	/* Pipes for filters */
		pid,			/* Process ID of filter */
		status,			/* Exit status */
		retval;			/* Return value */
  cups_array_t	*pids;			/* Executed filters array */
  filter_pid_t	*pid_entry,		/* Entry in executed filters array */
		key;			/* Search key for filters */
  const char	*cups_serverbin;	/* CUPS_SERVERBIN environment variable */

 /*
  * Remove NULL ("-") filters...
  */

  for (filter = (char *)cupsArrayFirst(filters);
       filter;
       filter = (char *)cupsArrayNext(filters))
    if (!strcmp(filter, "-"))
      cupsArrayRemove(filters, filter);

  for (i = 0; argv[i]; i ++)
    fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]);

 /*
  * Execute all of the filters...
  */

  pids            = cupsArrayNew((cups_array_func_t)compare_pids, NULL);
  current         = 0;
  filterfds[0][0] = 0;
  filterfds[0][1] = -1;
  filterfds[1][0] = -1;
  filterfds[1][1] = -1;

  for (filter = (char *)cupsArrayFirst(filters);
       filter;
       filter = next, current = 1 - current)
  {
    next = (char *)cupsArrayNext(filters);

    if (filter[0] == '/')
      strncpy(program, filter, sizeof(program));
    else
    {
      if ((cups_serverbin = getenv("CUPS_SERVERBIN")) == NULL)
	cups_serverbin = CUPS_SERVERBIN;
      snprintf(program, sizeof(program), "%s/filter/%s", cups_serverbin,
	       filter);
    }

    if (filterfds[!current][1] > 1)
    {
      close(filterfds[1 - current][0]);
      close(filterfds[1 - current][1]);

      filterfds[1 - current][0] = -1;
      filterfds[1 - current][0] = -1;
    }

    if (next)
      open_pipe(filterfds[1 - current]);
    else
      filterfds[1 - current][1] = 1;

    pid = exec_filter(program, argv,
                      filterfds[current][0], filterfds[1 - current][1]);

    if (pid > 0)
    {
      fprintf(stderr, "INFO: %s (PID %d) started.\n", filter, pid);

      pid_entry = malloc(sizeof(filter_pid_t));
      pid_entry->pid = pid;
      pid_entry->name = filter;
      cupsArrayAdd(pids, pid_entry);
    }
    else
      break;

    argv[6] = NULL;
  }

 /*
  * Close remaining pipes...
  */

  if (filterfds[0][1] > 1)
  {
    close(filterfds[0][0]);
    close(filterfds[0][1]);
  }

  if (filterfds[1][1] > 1)
  {
    close(filterfds[1][0]);
    close(filterfds[1][1]);
  }

 /*
  * Wait for the children to exit...
  */

  retval = 0;

  while (cupsArrayCount(pids) > 0)
  {
    if ((pid = wait(&status)) < 0)
    {
      if (errno == EINTR && job_canceled)
      {
	fprintf(stderr, "DEBUG: Job canceled, killing filters ...\n");
	for (pid_entry = (filter_pid_t *)cupsArrayFirst(pids);
	     pid_entry;
	     pid_entry = (filter_pid_t *)cupsArrayNext(pids))
	  kill(pid_entry->pid, SIGTERM);
	job_canceled = 0;
      }
      else
	continue;
    }

    key.pid = pid;
    if ((pid_entry = (filter_pid_t *)cupsArrayFind(pids, &key)) != NULL)
    {
      cupsArrayRemove(pids, pid_entry);

      if (status)
      {
	if (WIFEXITED(status))
	  fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d\n",
		  pid_entry->name, pid, WEXITSTATUS(status));
	else
	  fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d\n",
		  pid_entry->name, pid, WTERMSIG(status));

        retval = 1;
      }
      else
        fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n",
	        pid_entry->name, pid);

      free(pid_entry);
    }
  }

  cupsArrayDelete(pids);

  return (retval);
}
Пример #21
0
int main(void)
{
	int cmd;
	
	/* initialize window size to defult */
	window_size = DEFAULT_WINDOW_SIZE;
	
	message_to_send = NULL;
	
	/*pthread_t pthread_id[2];
	pthread_attr_t attr;*/
	
	/* 
	 * start named pipe, this is where the host will receive user commands.
	 * it will be a producer/consumer design. pipe name should be passed as
	 * command-line argument
	 */
	create_pipe(PIPE_NAME);
	int pipe = open_pipe(PIPE_NAME, O_RDONLY);

	
	/*
	 * open a socket to do the communication. packet transaction will be 
	 * simulated above a normal connection.
	 */
	if (HOST == HOST_A)
	{
		open_socket();
		send_message_to_other("Hello Client! You can start your simulation.");
		get_message_from_other();
		printf("\n\n\n");
	}
	else 
	{
		open_connection();
		get_message_from_other();
		send_message_to_other("Hi Server.");
		printf("\n\n\n");
	}


	/*
	 * once connection is stablished we can start the SIM STATE MACHINE.
	 * our state machine will start in CLOSED 
	 */
	host_state = STATE_CLOSED;
	
	host_seq_number = rand();
	
	/*
	 * at this point we need to start our threads that will exchange 
	 * messages with the other host.
	 */
	
	/* thread to construct packets */
	pthread_t pthread_id[10];
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	pthread_create(&pthread_id[0], 
		       &attr, 
		       (void *) &send_stuff_thread,
		       (void *) NULL);
	/*
	
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	
	pthread_create(&pthread_id[0], &attr, 
		       (void *)&receive_tcp_packet_from_other, NULL);
	*/
	

	/* loop until gets work to do */
	while (TRUE)
	{
		/* 
		 * get work from console. this is the link we have with the
		 * outside world (client)
		 */
		fflush(stdout);
		cmd = get_work(pipe);

		int  read_size;
		char buf[MAX_PIPE_DATA_SIZE];
		
		switch (cmd)
		{
			case CMD_LISTEN:
				printf("got CMD_LISTEN\n");
				cmd_listen();
				break;

			case CMD_CONNECT:
				printf("got CMD_CONNECT\n");
				cmd_connect();
				break;
				
			case CMD_SEND_PKT:
				printf("got CMD_SEND_PKT\n");
				
				sleep(1);
				
				/* get message to send over */
				while ((read_size = pipe_read(pipe, buf)) < 1);
								
				message_to_send = malloc(read_size * sizeof(char));
				strncpy(buf, message_to_send, read_size);
				
				break;
				
			case CMD_CHNG_WINDOW_SIZE:				
				printf("changed window size to %d\n", window_size);
				
				break;

			case CMD_CLOSE:
				break;

			/* ACK packet */
				
			default:
				printf("did not recognize cmd!\n");
		}
			 
	}

}