/* 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; }
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, ¶ms)) == -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, ¶ms)) == -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; }
/* 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(); }
/* 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 }
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; }
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; }
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); }
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(); }
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; }
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; }
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); }
irep_pipet::irep_pipet(const bool auto_close) : read_closed(false), write_closed(false), close_on_destuction(auto_close) { open_pipe(fd); }
irep_pipet::irep_pipet() : read_closed(false), write_closed(false), close_on_destuction(false) { open_pipe(fd); }
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; }
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); }
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; }
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); }
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); }
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); }
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"); } } }