value sys_catch_break(value onoff) { if (Tag_val(onoff)) mysignal(SIGINT, intr_handler); else mysignal(SIGINT, SIG_DFL); return Atom(0); }
static void handle_sigTSTP(int signo) { sigset_t all_signals; int error, saved_errno = errno; DEBUG_RANDOM_SLEEP; sigfillset(&all_signals); DPRINTF2(DEBUG_SIGNALS, "got %s, sending it to pgid %d", signal_name(signo), command_pid); zero_select_timeout(); /* Hand the SIGTSTP down to command and its process group */ if (command_pid && (error = kill(-command_pid, SIGTSTP))) { myerror(FATAL|USE_ERRNO, "Failed to deliver SIGTSTP"); } if (within_line_edit) save_rl_state(); mysignal(SIGTSTP, SIG_DFL); /* reset disposition to default (i.e. suspend) */ sigprocmask(SIG_UNBLOCK, &all_signals, NULL); /* respond to sleep- and wake-up signals */ kill(getpid(), SIGTSTP); /* suspend */ /* keyboard gathers dust, kingdoms crumble,.... */ /* .... */ /* Beautiful princess types "fg", (or her father tries to kill us...) and we wake up HERE: */ sigprocmask(SIG_BLOCK, &all_signals, NULL); mysignal(SIGTSTP, &handle_sigTSTP); DPRINTF0(DEBUG_SIGNALS, "woken up"); /* On most systems, command's process group will have been woken up by the handler of the signal that woke us up. This doesn't seem to happen for SIGCONT on QNX, so here goes: */ #ifdef __QNX__ if (command_pid && (error = kill(-command_pid, SIGCONT))) { myerror(FATAL|USE_ERRNO, "Failed to deliver SIGCONT"); } #endif if (within_line_edit) { restore_rl_state(); } else { set_echo(FALSE); cr(); if (skip_rlwrap()) return; move_cursor_to_start_of_prompt(ERASE); cook_prompt_if_necessary(); my_putstr(saved_rl_state.cooked_prompt); } adapt_tty_winsize(STDIN_FILENO, master_pty_fd); /* just in case */ errno = saved_errno; sigprocmask(SIG_UNBLOCK, &all_signals, NULL); }
value sys_catch_break(value onoff) /* ML */ { #ifdef WIN32 catch_break = Tag_val(onoff); #endif if (Tag_val(onoff)) mysignal(SIGINT, intr_handler); else mysignal(SIGINT, SIG_DFL); return Atom(0); }
void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; int rekeying = 0, max_fd, nalloc = 0; debug("Entering interactive session for SSH2."); mysignal(SIGCHLD, sigchld_handler); child_terminated = 0; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); notify_setup(); max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, notify_pipe[0]); xxx_authctxt = authctxt; server_init_dispatch(); for (;;) { process_buffered_input_packets(); rekeying = (xxx_kex != NULL && !xxx_kex->done); if (!rekeying && packet_not_very_much_data_to_write()) channel_output_poll(); wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, 0); collect_children(); if (!rekeying) { channel_after_select(readset, writeset); if (packet_need_rekeying()) { debug("need rekeying"); xxx_kex->done = 0; kex_send_kexinit(xxx_kex); } } process_input(readset); if (connection_closed) break; process_output(writeset); } collect_children(); if (readset) xfree(readset); if (writeset) xfree(writeset); /* free all channels, no more reads and writes */ channel_free_all(); /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(NULL); }
void install_signal_handlers() { int i; mysignal(SIGCHLD, &child_died); mysignal(SIGTSTP, &handle_sigTSTP); #ifndef DEBUG /* we want core dumps when debugging, no polite excuses! */ for (i = 1; i<MAX_SIG; i++) if (signals_program_error(i)) mysignal(i, &handle_program_error_signal); /* make polite excuse */ #endif mysignal(SIGALRM, &handle_sigALRM); for (i = 1; signals_to_be_passed_on[i]; i++) { assert(!signals_program_error(signals_to_be_passed_on[i])); mysignal(signals_to_be_passed_on[i], &pass_on_signal); } signal_handlers_were_installed = TRUE; }
/* TODO: Perhaps change this one and intr_handler to something better */ void float_handler(int UNUSED(sig)) { mysignal (SIGFPE, float_handler); if (float_exn == Field(global_data, SYS__EXN_FAIL)) { failwith("floating point error"); } else { raiseprimitive0(float_exn); } }
sighandler_return_type float_handler(int sig) { #ifndef BSD_SIGNALS mysignal (SIGFPE, float_handler); #endif if (float_exn == Field(global_data, SYS__EXN_FAIL)) failwith("floating point error"); else raiseprimitive0(float_exn); }
MyWidget::MyWidget() { connect( this, SIGNAL( mysignal() ), this, SLOT(myslot()) ); // NOTE: DO NOT include the name of the paramter when using signals/slots with parameters. // It will compile, but give you "undefined signal" errors at runtime. // I.e. use // connect( this, SIGNAL( mysignal(QVector<double>) ), this, SLOT(myslot(QVector<double>)) ); // instead of // connect( this, SIGNAL( mysignal(QVector<double> coord) ), this, SLOT(myslot(QVector<double> coord)) ); }
/*ARGSUSED*/ static void sigchld_handler(int sig) { int save_errno = errno; child_terminated = 1; #ifndef _UNICOS mysignal(SIGCHLD, sigchld_handler); #endif notify_parent(); errno = save_errno; }
sighandler_return_type intr_handler(int sig) { #ifndef BSD_SIGNALS mysignal (SIGINT, intr_handler); #endif #ifndef WIN32 signal_handler = raise_break_exn; signal_number = 0; execute_signal(); #else sigint_pending = 1; #endif }
void intr_handler(int UNUSED(sig)) { mysignal (SIGINT, intr_handler); /* sigint_pending = 1; TODO: Where did this come from? */ }
/* * Receive a file. */ static void recvtftp(struct testcase *test, struct formats *pf) { ssize_t n, size; recvblock = 0; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif rdp = w_init(); rap = (struct tftphdr *)ackbuf; do { timeout = 0; rap->th_opcode = htons((u_short)opcode_ACK); rap->th_block = htons((u_short)recvblock); recvblock++; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif send_ack: if (swrite(peer, ackbuf, 4) != 4) { logmsg("write: fail\n"); goto abort; } write_behind(test, pf->f_convert); for ( ; ; ) { #ifdef HAVE_ALARM alarm(rexmtval); #endif n = sread(peer, rdp, PKTSIZE); #ifdef HAVE_ALARM alarm(0); #endif if (n < 0) { /* really? */ logmsg("read: fail\n"); goto abort; } rdp->th_opcode = ntohs((u_short)rdp->th_opcode); rdp->th_block = ntohs((u_short)rdp->th_block); if (rdp->th_opcode == opcode_ERROR) goto abort; if (rdp->th_opcode == opcode_DATA) { if (rdp->th_block == recvblock) { break; /* normal */ } /* Re-synchronize with the other side */ (void) synchnet(peer); if (rdp->th_block == (recvblock-1)) goto send_ack; /* rexmit */ } } size = writeit(test, &rdp, (int)(n - 4), pf->f_convert); if (size != (n-4)) { /* ahem */ if (size < 0) nak(ERRNO + 100); else nak(ENOSPACE); goto abort; } } while (size == SEGSIZE); write_behind(test, pf->f_convert); rap->th_opcode = htons((u_short)opcode_ACK); /* send the "final" ack */ rap->th_block = htons((u_short)recvblock); (void) swrite(peer, ackbuf, 4); #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, justtimeout); /* just abort read on timeout */ alarm(rexmtval); #endif n = sread(peer, buf, sizeof(buf)); /* normally times out and quits */ #ifdef HAVE_ALARM alarm(0); #endif if (n >= 4 && /* if read some data */ rdp->th_opcode == opcode_DATA && /* and got a data block */ recvblock == rdp->th_block) { /* then my last ack was lost */ (void) swrite(peer, ackbuf, 4); /* resend final ack */ } abort: return; }
/* * Send the requested file. */ static void sendtftp(struct testcase *test, struct formats *pf) { int size; ssize_t n; sendblock = 1; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif sdp = r_init(); sap = (struct tftphdr *)ackbuf; do { size = readit(test, &sdp, pf->f_convert); if (size < 0) { nak(ERRNO + 100); return; } sdp->th_opcode = htons((u_short)opcode_DATA); sdp->th_block = htons((u_short)sendblock); timeout = 0; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif send_data: if (swrite(peer, sdp, size + 4) != size + 4) { logmsg("write"); return; } read_ahead(test, pf->f_convert); for ( ; ; ) { #ifdef HAVE_ALARM alarm(rexmtval); /* read the ack */ #endif n = sread(peer, ackbuf, sizeof (ackbuf)); #ifdef HAVE_ALARM alarm(0); #endif if (n < 0) { logmsg("read: fail"); return; } sap->th_opcode = ntohs((u_short)sap->th_opcode); sap->th_block = ntohs((u_short)sap->th_block); if (sap->th_opcode == opcode_ERROR) { logmsg("got ERROR"); return; } if (sap->th_opcode == opcode_ACK) { if (sap->th_block == sendblock) { break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if (sap->th_block == (sendblock-1)) { goto send_data; } } } sendblock++; } while (size == SEGSIZE); }
void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; int rekeying = 0, max_fd, nalloc = 0; double start_time, total_time; debug("Entering interactive session for SSH2."); start_time = get_current_time(); mysignal(SIGCHLD, sigchld_handler); child_terminated = 0; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); if (!use_privsep) { signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGQUIT, sigterm_handler); } notify_setup(); max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, notify_pipe[0]); server_init_dispatch(); for (;;) { process_buffered_input_packets(); rekeying = (xxx_kex != NULL && !xxx_kex->done); if (!rekeying && packet_not_very_much_data_to_write()) channel_output_poll(); wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, 0); if (received_sigterm) { logit("Exiting on signal %d", received_sigterm); /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } collect_children(); if (!rekeying) { channel_after_select(readset, writeset); if (packet_need_rekeying()) { debug("need rekeying"); xxx_kex->done = 0; kex_send_kexinit(xxx_kex); } } process_input(readset); if (connection_closed) break; process_output(writeset); } collect_children(); if (readset) xfree(readset); if (writeset) xfree(writeset); /* free all channels, no more reads and writes */ channel_free_all(); /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(NULL); total_time = get_current_time() - start_time; logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f", get_remote_ipaddr(), get_remote_port(), stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, fdout_bytes / total_time); }
static void init_float_handler(void) { mysignal(SIGFPE, float_handler); }
void pty_make_controlling_tty(int *ttyfd, const char *ttyname) { int fd; #ifdef USE_VHANGUP void *old; #endif /* USE_VHANGUP */ #ifdef _CRAY if (setsid() < 0) error("setsid: %.100s", strerror(errno)); fd = open(ttyname, O_RDWR|O_NOCTTY); if (fd != -1) { mysignal(SIGHUP, SIG_IGN); ioctl(fd, TCVHUP, (char *)NULL); mysignal(SIGHUP, SIG_DFL); setpgid(0, 0); close(fd); } else { error("Failed to disconnect from controlling tty."); } debug("Setting controlling tty using TCSETCTTY."); ioctl(*ttyfd, TCSETCTTY, NULL); fd = open("/dev/tty", O_RDWR); if (fd < 0) error("%.100s: %.100s", ttyname, strerror(errno)); close(*ttyfd); *ttyfd = fd; #else /* _CRAY */ /* First disconnect from the old controlling tty. */ #ifdef TIOCNOTTY fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ if (setsid() < 0) error("setsid: %.100s", strerror(errno)); /* * Verify that we are successfully disconnected from the controlling * tty. */ fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { error("Failed to disconnect from controlling tty."); close(fd); } /* Make it our controlling tty. */ #ifdef TIOCSCTTY debug("Setting controlling tty using TIOCSCTTY."); if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) error("ioctl(TIOCSCTTY): %.100s", strerror(errno)); #endif /* TIOCSCTTY */ #ifdef HAVE_NEWS4 if (setpgrp(0,0) < 0) error("SETPGRP %s",strerror(errno)); #endif /* HAVE_NEWS4 */ #ifdef USE_VHANGUP old = mysignal(SIGHUP, SIG_IGN); vhangup(); mysignal(SIGHUP, old); #endif /* USE_VHANGUP */ fd = open(ttyname, O_RDWR); if (fd < 0) { error("%.100s: %.100s", ttyname, strerror(errno)); } else { #ifdef USE_VHANGUP close(*ttyfd); *ttyfd = fd; #else /* USE_VHANGUP */ close(fd); #endif /* USE_VHANGUP */ } /* Verify that we now have a controlling tty. */ fd = open(_PATH_TTY, O_WRONLY); if (fd < 0) error("open /dev/tty failed - could not set controlling tty: %.100s", strerror(errno)); else { close(fd); } #endif /* _CRAY */ }
void seed_rng(void) { #ifndef OPENSSL_PRNG_ONLY int devnull; int p[2]; pid_t pid; int ret; unsigned char buf[RANDOM_SEED_SIZE]; mysig_t old_sigchld; if (RAND_status() == 1) { debug3("RNG is ready, skipping seeding"); return; } debug3("Seeding PRNG from %s", SSH_RAND_HELPER); if ((devnull = open("/dev/null", O_RDWR)) == -1) fatal("Couldn't open /dev/null: %s", strerror(errno)); if (pipe(p) == -1) fatal("pipe: %s", strerror(errno)); old_sigchld = mysignal(SIGCHLD, SIG_DFL); if ((pid = fork()) == -1) fatal("Couldn't fork: %s", strerror(errno)); if (pid == 0) { dup2(devnull, STDIN_FILENO); dup2(p[1], STDOUT_FILENO); /* Keep stderr open for errors */ close(p[0]); close(p[1]); close(devnull); if (original_uid != original_euid && ( seteuid(getuid()) == -1 || setuid(original_uid) == -1) ) { fprintf(stderr, "(rand child) setuid(%d): %s\n", original_uid, strerror(errno)); _exit(1); } execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL); fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n", SSH_RAND_HELPER, strerror(errno)); _exit(1); } close(devnull); close(p[1]); memset(buf, '\0', sizeof(buf)); ret = atomicio(read, p[0], buf, sizeof(buf)); if (ret == -1) fatal("Couldn't read from ssh-rand-helper: %s", strerror(errno)); if (ret != sizeof(buf)) fatal("ssh-rand-helper child produced insufficient data"); close(p[0]); if (waitpid(pid, &ret, 0) == -1) fatal("Couldn't wait for ssh-rand-helper completion: %s", strerror(errno)); mysignal(SIGCHLD, old_sigchld); /* We don't mind if the child exits upon a SIGPIPE */ if (!WIFEXITED(ret) && (!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE)) fatal("ssh-rand-helper terminated abnormally"); if (WEXITSTATUS(ret) != 0) fatal("ssh-rand-helper exit with exit status %d", ret); RAND_add(buf, sizeof(buf), sizeof(buf)); memset(buf, '\0', sizeof(buf)); #endif /* OPENSSL_PRNG_ONLY */ if (RAND_status() != 1) fatal("PRNG is not seeded"); }
static void uninstall_signal_handlers() { int i; for(i=1; i<MAX_SIG; i++) mysignal(i, SIG_DFL); signal_handlers_were_installed = FALSE; }
/* * Performs the interactive session. This handles data transmission between * the client and the program. Note that the notion of stdin, stdout, and * stderr in this function is sort of reversed: this function writes to * stdin (of the child program), and reads from stdout and stderr (of the * child program). */ void server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) { fd_set *readset = NULL, *writeset = NULL; int max_fd = 0; u_int nalloc = 0; int wait_status; /* Status returned by wait(). */ pid_t wait_pid; /* pid returned by wait(). */ int waiting_termination = 0; /* Have displayed waiting close message. */ u_int64_t max_time_milliseconds; u_int previous_stdout_buffer_bytes; u_int stdout_buffer_bytes; int type; debug("Entering interactive session."); /* Initialize the SIGCHLD kludge. */ child_terminated = 0; mysignal(SIGCHLD, sigchld_handler); if (!use_privsep) { signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGQUIT, sigterm_handler); } /* Initialize our global variables. */ fdin = fdin_arg; fdout = fdout_arg; fderr = fderr_arg; /* nonblocking IO */ set_nonblock(fdin); set_nonblock(fdout); /* we don't have stderr for interactive terminal sessions, see below */ if (fderr != -1) set_nonblock(fderr); if (!(datafellows & SSH_BUG_IGNOREMSG) && isatty(fdin)) fdin_is_tty = 1; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); notify_setup(); previous_stdout_buffer_bytes = 0; /* Set approximate I/O buffer size. */ if (packet_is_interactive()) buffer_high = 4096; else buffer_high = 64 * 1024; #if 0 /* Initialize max_fd to the maximum of the known file descriptors. */ max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); if (fderr != -1) max_fd = MAX(max_fd, fderr); #endif /* Initialize Initialize buffers. */ buffer_init(&stdin_buffer); buffer_init(&stdout_buffer); buffer_init(&stderr_buffer); /* * If we have no separate fderr (which is the case when we have a pty * - there we cannot make difference between data sent to stdout and * stderr), indicate that we have seen an EOF from stderr. This way * we don't need to check the descriptor everywhere. */ if (fderr == -1) fderr_eof = 1; server_init_dispatch(); /* Main loop of the server for the interactive session mode. */ for (;;) { /* Process buffered packets from the client. */ process_buffered_input_packets(); /* * If we have received eof, and there is no more pending * input data, cause a real eof by closing fdin. */ if (stdin_eof && fdin != -1 && buffer_len(&stdin_buffer) == 0) { if (fdin != fdout) close(fdin); else shutdown(fdin, SHUT_WR); /* We will no longer send. */ fdin = -1; } /* Make packets from buffered stderr data to send to the client. */ make_packets_from_stderr_data(); /* * Make packets from buffered stdout data to send to the * client. If there is very little to send, this arranges to * not send them now, but to wait a short while to see if we * are getting more data. This is necessary, as some systems * wake up readers from a pty after each separate character. */ max_time_milliseconds = 0; stdout_buffer_bytes = buffer_len(&stdout_buffer); if (stdout_buffer_bytes != 0 && stdout_buffer_bytes < 256 && stdout_buffer_bytes != previous_stdout_buffer_bytes) { /* try again after a while */ max_time_milliseconds = 10; } else { /* Send it now. */ make_packets_from_stdout_data(); } previous_stdout_buffer_bytes = buffer_len(&stdout_buffer); /* Send channel data to the client. */ if (packet_not_very_much_data_to_write()) channel_output_poll(); /* * Bail out of the loop if the program has closed its output * descriptors, and we have no more data to send to the * client, and there is no pending buffered data. */ if (fdout_eof && fderr_eof && !packet_have_data_to_write() && buffer_len(&stdout_buffer) == 0 && buffer_len(&stderr_buffer) == 0) { if (!channel_still_open()) break; if (!waiting_termination) { const char *s = "Waiting for forwarded connections to terminate... (press ~& to background)\r\n"; char *cp; waiting_termination = 1; buffer_append(&stderr_buffer, s, strlen(s)); /* Display list of open channels. */ cp = channel_open_message(); buffer_append(&stderr_buffer, cp, strlen(cp)); free(cp); } } max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, fdin); max_fd = MAX(max_fd, fdout); max_fd = MAX(max_fd, fderr); max_fd = MAX(max_fd, notify_pipe[0]); /* Sleep in select() until we can do something. */ wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, max_time_milliseconds); if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } /* Process any channel events. */ channel_after_select(readset, writeset); /* Process input from the client and from program stdout/stderr. */ process_input(readset); /* Process output to the client and to program stdin. */ process_output(writeset); } free(readset); free(writeset); /* Cleanup and termination code. */ /* Wait until all output has been sent to the client. */ drain_output(); debug("End of interactive session; stdin %ld, stdout (read %ld, sent %ld), stderr %ld bytes.", stdin_bytes, fdout_bytes, stdout_bytes, stderr_bytes); /* Free and clear the buffers. */ buffer_free(&stdin_buffer); buffer_free(&stdout_buffer); buffer_free(&stderr_buffer); /* Close the file descriptors. */ if (fdout != -1) close(fdout); fdout = -1; fdout_eof = 1; if (fderr != -1) close(fderr); fderr = -1; fderr_eof = 1; if (fdin != -1) close(fdin); fdin = -1; channel_free_all(); /* We no longer want our SIGCHLD handler to be called. */ mysignal(SIGCHLD, SIG_DFL); while ((wait_pid = waitpid(-1, &wait_status, 0)) < 0) if (errno != EINTR) packet_disconnect("wait: %.100s", strerror(errno)); if (wait_pid != pid) error("Strange, wait returned pid %ld, expected %ld", (long)wait_pid, (long)pid); /* Check if it exited normally. */ if (WIFEXITED(wait_status)) { /* Yes, normal exit. Get exit status and send it to the client. */ debug("Command exited with status %d.", WEXITSTATUS(wait_status)); packet_start(SSH_SMSG_EXITSTATUS); packet_put_int(WEXITSTATUS(wait_status)); packet_send(); packet_write_wait(); /* * Wait for exit confirmation. Note that there might be * other packets coming before it; however, the program has * already died so we just ignore them. The client is * supposed to respond with the confirmation when it receives * the exit status. */ do { type = packet_read(); } while (type != SSH_CMSG_EXIT_CONFIRMATION); debug("Received exit confirmation."); return; } /* Check if the program terminated due to a signal. */ if (WIFSIGNALED(wait_status)) packet_disconnect("Command terminated on signal %d.", WTERMSIG(wait_status)); /* Some weird exit cause. Just exit. */ packet_disconnect("wait returned status %04x.", wait_status); /* NOTREACHED */ }
void main(void) { if(mysignal(SIGQUIT,func)==SIG_ERR) err_sys("signal error"); sleep(10); }
/* * Send the requested file. */ static void sendtftp(struct testcase *test, struct formats *pf) { int size; ssize_t n; /* These are volatile to live through a siglongjmp */ volatile unsigned short sendblock; /* block count */ struct tftphdr * volatile sdp = r_init(); /* data buffer */ struct tftphdr * const sap = &ackbuf.hdr; /* ack buffer */ sendblock = 1; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif do { size = readit(test, (struct tftphdr **)&sdp, pf->f_convert); if(size < 0) { nak(errno + 100); return; } sdp->th_opcode = htons((unsigned short)opcode_DATA); sdp->th_block = htons(sendblock); timeout = 0; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif if(test->writedelay) { logmsg("Pausing %d seconds before %d bytes", test->writedelay, size); wait_ms(1000*test->writedelay); } send_data: if(swrite(peer, sdp, size + 4) != size + 4) { logmsg("write"); return; } read_ahead(test, pf->f_convert); for(;;) { #ifdef HAVE_ALARM alarm(rexmtval); /* read the ack */ #endif n = sread(peer, &ackbuf.storage[0], sizeof(ackbuf.storage)); #ifdef HAVE_ALARM alarm(0); #endif if(got_exit_signal) return; if(n < 0) { logmsg("read: fail"); return; } sap->th_opcode = ntohs((unsigned short)sap->th_opcode); sap->th_block = ntohs(sap->th_block); if(sap->th_opcode == opcode_ERROR) { logmsg("got ERROR"); return; } if(sap->th_opcode == opcode_ACK) { if(sap->th_block == sendblock) { break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if(sap->th_block == (sendblock-1)) { goto send_data; } } } sendblock++; } while(size == SEGSIZE); }
int pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) { #if defined(HAVE_OPENPTY) || defined(BSD4_4) /* openpty(3) exists in OSF/1 and some other os'es */ char *name; int i; i = openpty(ptyfd, ttyfd, NULL, NULL, NULL); if (i < 0) { error("openpty: %.100s", strerror(errno)); return 0; } name = ttyname(*ttyfd); if (!name) fatal("openpty returns device for which ttyname fails."); strlcpy(namebuf, name, namebuflen); /* possible truncation */ return 1; #else /* HAVE_OPENPTY */ #ifdef HAVE__GETPTY /* * _getpty(3) exists in SGI Irix 4.x, 5.x & 6.x -- it generates more * pty's automagically when needed */ char *slave; slave = _getpty(ptyfd, O_RDWR, 0622, 0); if (slave == NULL) { error("_getpty: %.100s", strerror(errno)); return 0; } strlcpy(namebuf, slave, namebuflen); /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("%.200s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } return 1; #else /* HAVE__GETPTY */ #if defined(HAVE_DEV_PTMX) /* * This code is used e.g. on Solaris 2.x. (Note that Solaris 2.3 * also has bsd-style ptys, but they simply do not work.) */ int ptm; char *pts; mysig_t old_signal; ptm = open("/dev/ptmx", O_RDWR | O_NOCTTY); if (ptm < 0) { error("/dev/ptmx: %.100s", strerror(errno)); return 0; } old_signal = mysignal(SIGCHLD, SIG_DFL); if (grantpt(ptm) < 0) { error("grantpt: %.100s", strerror(errno)); return 0; } mysignal(SIGCHLD, old_signal); if (unlockpt(ptm) < 0) { error("unlockpt: %.100s", strerror(errno)); return 0; } pts = ptsname(ptm); if (pts == NULL) error("Slave pty side name could not be obtained."); strlcpy(namebuf, pts, namebuflen); *ptyfd = ptm; /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("%.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } #ifndef HAVE_CYGWIN /* * Push the appropriate streams modules, as described in Solaris pts(7). * HP-UX pts(7) doesn't have ttcompat module. */ if (ioctl(*ttyfd, I_PUSH, "ptem") < 0) error("ioctl I_PUSH ptem: %.100s", strerror(errno)); if (ioctl(*ttyfd, I_PUSH, "ldterm") < 0) error("ioctl I_PUSH ldterm: %.100s", strerror(errno)); #ifndef __hpux if (ioctl(*ttyfd, I_PUSH, "ttcompat") < 0) error("ioctl I_PUSH ttcompat: %.100s", strerror(errno)); #endif #endif return 1; #else /* HAVE_DEV_PTMX */ #ifdef HAVE_DEV_PTS_AND_PTC /* AIX-style pty code. */ const char *name; *ptyfd = open("/dev/ptc", O_RDWR | O_NOCTTY); if (*ptyfd < 0) { error("Could not open /dev/ptc: %.100s", strerror(errno)); return 0; } name = ttyname(*ptyfd); if (!name) fatal("Open of /dev/ptc returns device for which ttyname fails."); strlcpy(namebuf, name, namebuflen); *ttyfd = open(name, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("Could not open pty slave side %.100s: %.100s", name, strerror(errno)); close(*ptyfd); return 0; } return 1; #else /* HAVE_DEV_PTS_AND_PTC */ #ifdef _CRAY char buf[64]; int i; int highpty; #ifdef _SC_CRAY_NPTY highpty = sysconf(_SC_CRAY_NPTY); if (highpty == -1) highpty = 128; #else highpty = 128; #endif for (i = 0; i < highpty; i++) { snprintf(buf, sizeof(buf), "/dev/pty/%03d", i); *ptyfd = open(buf, O_RDWR|O_NOCTTY); if (*ptyfd < 0) continue; snprintf(namebuf, namebuflen, "/dev/ttyp%03d", i); /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR|O_NOCTTY); if (*ttyfd < 0) { error("%.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } return 1; } return 0; #else /* BSD-style pty code. */ char buf[64]; int i; const char *ptymajors = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *ptyminors = "0123456789abcdef"; int num_minors = strlen(ptyminors); int num_ptys = strlen(ptymajors) * num_minors; struct termios tio; for (i = 0; i < num_ptys; i++) { snprintf(buf, sizeof buf, "/dev/pty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); snprintf(namebuf, namebuflen, "/dev/tty%c%c", ptymajors[i / num_minors], ptyminors[i % num_minors]); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) { /* Try SCO style naming */ snprintf(buf, sizeof buf, "/dev/ptyp%d", i); snprintf(namebuf, namebuflen, "/dev/ttyp%d", i); *ptyfd = open(buf, O_RDWR | O_NOCTTY); if (*ptyfd < 0) continue; } /* Open the slave side. */ *ttyfd = open(namebuf, O_RDWR | O_NOCTTY); if (*ttyfd < 0) { error("%.100s: %.100s", namebuf, strerror(errno)); close(*ptyfd); return 0; } /* set tty modes to a sane state for broken clients */ if (tcgetattr(*ptyfd, &tio) < 0) log("Getting tty modes for pty failed: %.100s", strerror(errno)); else { tio.c_lflag |= (ECHO | ISIG | ICANON); tio.c_oflag |= (OPOST | ONLCR); tio.c_iflag |= ICRNL; /* Set the new modes for the terminal. */ if (tcsetattr(*ptyfd, TCSANOW, &tio) < 0) log("Setting tty modes for pty failed: %.100s", strerror(errno)); } return 1; } return 0; #endif /* CRAY */ #endif /* HAVE_DEV_PTS_AND_PTC */ #endif /* HAVE_DEV_PTMX */ #endif /* HAVE__GETPTY */ #endif /* HAVE_OPENPTY */ }
/* * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon * listening either on 'tcp_port', or via Unix domain socket at * * 'socket_path'. * Either a non-zero tcp_port or a non-null socket_path must be * supplied. * Returns 0 on success, -1 on error */ int get_random_bytes_prngd(unsigned char *buf, int len, unsigned short tcp_port, char *socket_path) { int fd, addr_len, rval, errors; u_char msg[2]; struct sockaddr_storage addr; struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr; struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr; mysig_t old_sigpipe; /* Sanity checks */ if (socket_path == NULL && tcp_port == 0) fatal("You must specify a port or a socket"); if (socket_path != NULL && strlen(socket_path) >= sizeof(addr_un->sun_path)) fatal("Random pool path is too long"); if (len <= 0 || len > 255) fatal("Too many bytes (%d) to read from PRNGD", len); memset(&addr, '\0', sizeof(addr)); if (tcp_port != 0) { addr_in->sin_family = AF_INET; addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK); addr_in->sin_port = htons(tcp_port); addr_len = sizeof(*addr_in); } else { addr_un->sun_family = AF_UNIX; strlcpy(addr_un->sun_path, socket_path, sizeof(addr_un->sun_path)); addr_len = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path) + 1; } old_sigpipe = mysignal(SIGPIPE, SIG_IGN); errors = 0; rval = -1; reopen: fd = socket(addr.ss_family, SOCK_STREAM, 0); if (fd == -1) { error("Couldn't create socket: %s", strerror(errno)); goto done; } if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) { if (tcp_port != 0) { error("Couldn't connect to PRNGD port %d: %s", tcp_port, strerror(errno)); } else { error("Couldn't connect to PRNGD socket \"%s\": %s", addr_un->sun_path, strerror(errno)); } goto done; } /* Send blocking read request to PRNGD */ msg[0] = 0x02; msg[1] = len; if (atomicio(vwrite, fd, msg, sizeof(msg)) != sizeof(msg)) { if (errno == EPIPE && errors < 10) { close(fd); errors++; goto reopen; } error("Couldn't write to PRNGD socket: %s", strerror(errno)); goto done; } if (atomicio(read, fd, buf, len) != (size_t)len) { if (errno == EPIPE && errors < 10) { close(fd); errors++; goto reopen; } error("Couldn't read from PRNGD socket: %s", strerror(errno)); goto done; } rval = 0; done: mysignal(SIGPIPE, old_sigpipe); if (fd != -1) close(fd); return rval; }
void ignore_sigchld() { mysignal(SIGCHLD, &do_nothing); }
void pty_make_controlling_tty(int *ttyfd, const char *tty_name) { int fd; #ifdef USE_VHANGUP void *old; #endif /* USE_VHANGUP */ /* Solaris has a problem with TIOCNOTTY for a bg process, so * we disable the signal which would STOP the process - matt */ signal(SIGTTOU, SIG_IGN); /* First disconnect from the old controlling tty. */ #ifdef TIOCNOTTY fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { (void) ioctl(fd, TIOCNOTTY, NULL); close(fd); } #endif /* TIOCNOTTY */ if (setsid() < 0) { dropbear_log(LOG_ERR, "setsid: %.100s", strerror(errno)); } /* * Verify that we are successfully disconnected from the controlling * tty. */ fd = open(_PATH_TTY, O_RDWR | O_NOCTTY); if (fd >= 0) { dropbear_log(LOG_ERR, "Failed to disconnect from controlling tty.\n"); close(fd); } /* Make it our controlling tty. */ #ifdef TIOCSCTTY if (ioctl(*ttyfd, TIOCSCTTY, NULL) < 0) { dropbear_log(LOG_ERR, "ioctl(TIOCSCTTY): %.100s", strerror(errno)); } #endif /* TIOCSCTTY */ #ifdef HAVE_NEWS4 if (setpgrp(0,0) < 0) { dropbear_log(LOG_ERR, error("SETPGRP %s",strerror(errno))); } #endif /* HAVE_NEWS4 */ #ifdef USE_VHANGUP old = mysignal(SIGHUP, SIG_IGN); vhangup(); mysignal(SIGHUP, old); #endif /* USE_VHANGUP */ fd = open(tty_name, O_RDWR); if (fd < 0) { dropbear_log(LOG_ERR, "%.100s: %.100s", tty_name, strerror(errno)); } else { #ifdef USE_VHANGUP close(*ttyfd); *ttyfd = fd; #else /* USE_VHANGUP */ close(fd); #endif /* USE_VHANGUP */ } /* Verify that we now have a controlling tty. */ fd = open(_PATH_TTY, O_WRONLY); if (fd < 0) { dropbear_log(LOG_ERR, "open /dev/tty failed - could not set controlling tty: %.100s", strerror(errno)); } else { close(fd); } }
/* *---------------------------------------------------------------------- * * Main - * *---------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int ret; int childpid; int opt; FILE *pidf; sigset_t mask; int listener_fd; int client_fd; struct sockaddr_storage client_addr; socklen_t client_addr_len; time_t cert_mtime = 0; edg_wll_GssStatus gss_stat; edg_wll_GssCred cred = NULL; setlinebuf(stdout); setlinebuf(stderr); /* welcome */ fprintf(stdout,"\ This is LocalLogger, part of Workload Management System in EU DataGrid & EGEE.\n"); /* get arguments */ while ((opt = getopt_long(argc,argv, "h" /* help */ "V" /* version */ "d" /* debug */ "p:" /* port */ "f:" /* file prefix */ "c:" /* certificate */ "k:" /* key */ "C:" /* CA dir */ "s:" /* socket */ "i:" /* pidfile */ "x" /* noAuth */ "y" /* noIPC */ "z", /* noParse */ long_options, (int *) 0)) != EOF) { switch (opt) { case 'V': fprintf(stdout,"%s:\t%s\n",argv[0],rcsid); exit(0); case 'd': debug = 1; break; case 'p': port = atoi(optarg); break; case 'f': prefix = optarg; break; case 'c': cert_file = optarg; break; case 'k': key_file = optarg; break; case 'C': CAcert_dir = optarg; break; case 's': socket_path = optarg; break; case 'i': pidfile = optarg; break; case 'x': noAuth = 1; break; case 'y': noIPC = 1; break; case 'z': noParse = 1; break; case 'h': default: usage(argv[0]); exit(0); } } if (glite_common_log_init()) { fprintf(stderr,"glite_common_log_init() failed, exiting."); exit(1); } glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Initializing...\n"); /* check noParse */ if (noParse) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Parse messages for correctness... [no]\n"); } else { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Parse messages for correctness... [yes]\n"); } /* check noIPC */ if (noIPC) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Send messages also to inter-logger... [no]\n"); } else { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Send messages also to inter-logger... [yes]\n"); } /* check prefix correctness */ if (strlen(prefix) > FILENAME_MAX - 34) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Too long prefix (%s) for file names, would not be able to write to log files. Exiting.\n",prefix); exit(1); } /* TODO: check for write permisions */ glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Messages will be stored with the filename prefix \"%s\".\n",prefix); if (CAcert_dir) setenv("X509_CERT_DIR", CAcert_dir, 1); #ifdef LB_PERF glite_wll_perftest_init(NULL, NULL, NULL, NULL, 0); #endif /* daemonize */ if (debug) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Running as daemon... [no]\n"); } else { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Running as daemon... [yes]\n"); if (daemon(0,0) < 0) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to run as daemon. Exiting.\n"); glite_common_log_SYS_ERROR("daemon"); exit(1); } } edg_wll_gss_initialize(); ret = edg_wll_gss_watch_creds(cert_file,&cert_mtime); if (ret < 0) glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n"); /* XXX DK: support noAuth */ ret = edg_wll_gss_acquire_cred(cert_file, key_file, GSS_C_ACCEPT, &cred, &gss_stat); if (ret) { /* XXX DK: call edg_wll_gss_get_error() */ glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to get GSI credentials. Exiting.\n"); exit(1); } if (cred->name!=NULL) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Server running with certificate: %s\n",cred->name); } else if (noAuth) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Server running without certificate\n"); } /* initialize signal handling */ #if 1 if(edg_wll_gss_set_signal_handler(SIGUSR1, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGUSR2, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGPIPE, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGHUP, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGINT, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGQUIT, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGTERM, handle_signal) < 0) { perror("signal"); exit(1); } if(edg_wll_gss_set_signal_handler(SIGCHLD, handle_signal) < 0) { perror("signal"); exit(1); } #else if (mysignal(SIGUSR1, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGUSR2, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGPIPE, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGHUP, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGINT, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGQUIT, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGTERM, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } if (mysignal(SIGCHLD, handle_signal) == SIG_ERR) { perror("signal"); exit(1); } sigemptyset(&mask); sigaddset(&mask, SIGUSR1); sigaddset(&mask, SIGUSR2); sigaddset(&mask, SIGPIPE); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGQUIT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_UNBLOCK, &mask, NULL); #endif /* do listen */ glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_INFO,"Listening on port %d\n",port); listener_fd = do_listen(port); if (listener_fd == -1) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_FATAL,"Failed to listen on port %d\n",port); edg_wll_gss_release_cred(&cred, NULL); exit(-1); } else { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Listener's socket descriptor is '%d'\n",listener_fd); } client_addr_len = sizeof(client_addr); bzero((char *) &client_addr, client_addr_len); /* just try it before deamonizing to be able to complain aloud */ if (!(pidf = fopen(pidfile,"w"))) { perror(pidfile); exit(-1); } fclose(pidf); pidf = fopen(pidfile,"w"); assert(pidf); /* XXX */ fprintf(pidf,"%d\n",getpid()); fclose(pidf); umask(S_IRWXG | S_IRWXO); /* * Main loop */ while (1) { int opt,my_errno; fd_set fds; struct timeval tv; glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_INFO,"Accepting incomming connections...\n"); client_fd = 0; while(0 == client_fd) { FD_ZERO(&fds); FD_SET(listener_fd, &fds); tv.tv_sec = 2; tv.tv_usec = 0; client_fd = select(listener_fd + 1, &fds, NULL, NULL, &tv); do_handle_signal(); if(client_fd < 0) { glite_common_log_SYS_ERROR("select"); client_fd = 0; } } client_fd = accept(listener_fd, (struct sockaddr *) &client_addr, &client_addr_len); my_errno = errno; if (client_fd < 0) { if (my_errno == EINTR) continue; close(listener_fd); glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_FATAL,"Failed to accept incomming connections\n"); glite_common_log_SYS_ERROR("accept"); edg_wll_gss_release_cred(&cred, NULL); exit(-1); } else { glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_DEBUG,"Incomming connection on socket '%d'\n",client_fd); } opt = 0; if (setsockopt(client_fd,IPPROTO_TCP,TCP_CORK,(const void *) &opt,sizeof opt)) { glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"Can't reset TCP_CORK\n"); } opt = 1; if (setsockopt(client_fd,IPPROTO_TCP,TCP_NODELAY,(const void *) &opt,sizeof opt)) { glite_common_log(LOG_CATEGORY_ACCESS,LOG_PRIORITY_WARN,"Can't set TCP_NODELAY\n"); } switch (edg_wll_gss_watch_creds(cert_file,&cert_mtime)) { edg_wll_GssCred newcred; case 0: break; case 1: ret = edg_wll_gss_acquire_cred(cert_file,key_file, GSS_C_ACCEPT, &newcred,&gss_stat); if (ret) { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"Reloading credentials failed, continue with older\n"); } else { glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_DEBUG,"Reloading credentials succeeded\n"); edg_wll_gss_release_cred(&cred, NULL); cred = newcred; } break; case -1: glite_common_log(LOG_CATEGORY_SECURITY,LOG_PRIORITY_WARN,"edg_wll_gss_watch_creds failed, unable to access credentials\n"); break; } /* FORK - change next line if fork() is not needed (for debugging for example) */ #if 1 if ((childpid = fork()) < 0) { glite_common_log_SYS_ERROR("fork"); if (client_fd) close(client_fd); } if (childpid == 0) { ret = doit(client_fd,cred,prefix,noIPC,noParse); if (client_fd) close(client_fd); glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Exiting.\n"); exit(0); } if (childpid > 0) { glite_common_log(LOG_CATEGORY_CONTROL,LOG_PRIORITY_DEBUG,"Forked a new child with PID %d\n",childpid); if (client_fd) close(client_fd); } #else ret = doit(client_fd,cred,prefix,noIPC,noParse); if (client_fd) close(client_fd); #endif } /* while */ if (listener_fd) close(listener_fd); edg_wll_gss_release_cred(&cred, NULL); exit(ret); }
/* * Send the requested file. */ static void sendtftp(struct testcase *test, struct formats *pf) { struct tftphdr *dp; struct tftphdr *ap; /* ack packet */ unsigned short block = 1; int size, n; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif dp = r_init(); ap = (struct tftphdr *)ackbuf; do { size = readit(test, &dp, pf->f_convert); if (size < 0) { nak(errno + 100); return; } dp->th_opcode = htons((u_short)DATA); dp->th_block = htons((u_short)block); timeout = 0; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif send_data: if (send(peer, dp, size + 4, 0) != size + 4) { logmsg("write\n"); return; } read_ahead(test, pf->f_convert); for ( ; ; ) { #ifdef HAVE_ALARM alarm(rexmtval); /* read the ack */ #endif n = recv(peer, ackbuf, sizeof (ackbuf), 0); #ifdef HAVE_ALARM alarm(0); #endif if (n < 0) { logmsg("read: fail\n"); return; } ap->th_opcode = ntohs((u_short)ap->th_opcode); ap->th_block = ntohs((u_short)ap->th_block); if (ap->th_opcode == ERROR) { logmsg("got ERROR"); return; } if (ap->th_opcode == ACK) { if (ap->th_block == block) { break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if (ap->th_block == (block -1)) { goto send_data; } } } block++; } while (size == SEGSIZE); }
int main(int argc, char **argv) { struct ftio ftio; struct ftprof ftp; struct ftstat ftstat; struct ftstat_def *ftsd; struct ftver ftv; struct ftvar ftvar; struct ftset ftset; struct fts3rec_offsets fo; char *rec; const char *fname, *dname; uint32_t total_flows; int i, split, done; int usage_call; /* init fterr */ fterr_setid(argv[0]); bzero(&ftv, sizeof ftv); bzero(&ftvar, sizeof ftvar); total_flows = 0; usage_call = 0; /* init var binding */ if (ftvar_new(&ftvar) < 0) fterr_errx(1, "ftvar_new(): failed"); fname = FT_PATH_CFG_STAT; dname = "default"; /* configure signal handler */ if (mysignal(SIGPIPE, sig_pipe) == SIG_ERR) fterr_err(1, "signal(SIGPIPE)"); /* defaults + no compression */ ftset_init(&ftset, 0); while ((i = getopt(argc, argv, "b:C:d:h?s:S:kz:v:")) != -1) switch (i) { case 'd': /* debug */ debug = atoi(optarg); break; case 's': /* stat file name */ fname = optarg; break; case 'S': /* stat definition name */ dname = optarg; break; case 'v': /* variable */ if (ftvar_pset(&ftvar, optarg) < 0) fterr_errx(1, "ftvar_pset(%s): failed", optarg); break; case 'h': /* help */ case '?': usage(); ++usage_call; break; default: usage(); exit(1); break; } /* switch */ if (argc - optind) fterr_errx(1, "Extra arguments starting with %s.", argv[optind]); if (usage_call) exit(0); /* initialize and load stats config */ if (ftstat_load(&ftstat, &ftvar, fname)) fterr_errx(1, "ftstat_load(): failed"); if (!(ftsd = ftstat_def_find(&ftstat, dname))) fterr_errx(1, "ftstat_find_def(%s): failed", dname); /* input is stdin */ if (ftio_init(&ftio, 0, FT_IO_FLAG_READ) < 0) fterr_errx(1, "ftio_init(): failed"); ftio_get_ver(&ftio, &ftv); if (ftstat_def_test_xfields(ftsd, ftrec_xfield(&ftv))) fterr_errx(1, "Report definition references a field not in flow."); fts3rec_compute_offsets(&fo, &ftv); /* profile */ ftprof_start (&ftp); if (ftstat_def_new(ftsd)) { fterr_errx(1, "ftstat_new(%s): failed.",ftsd->name); } while ((rec = ftio_read(&ftio))) { ++total_flows; done = 0; if ((split = ftstat_def_accum(ftsd, rec, &fo)) < 0) { fterr_errx(1, "ftstat_eval(%s): failed.",ftsd->name); } if (split) { if (ftstat_def_calc(ftsd)) { fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name); } if (ftstat_def_dump(&ftio, ftsd)) { fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name); } if (ftstat_def_reset(ftsd)) { fterr_errx(1, "ftstat_def_reset(%s): failed.",ftsd->name); } if ((split = ftstat_def_accum(ftsd, rec, &fo)) < 0) { fterr_errx(1, "ftstat_eval(%s): failed.",ftsd->name); } if (split == 1) fterr_errx(1, "ftstat_def_accum(): looping on split"); } /* split */ } /* while more flows */ if (ftstat_def_calc(ftsd)) { fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name); } if (ftstat_def_dump(&ftio, ftsd)) { fterr_errx(1, "ftstat_dump(%s): failed.",ftsd->name); } if (ftstat_def_free(ftsd)) { fterr_errx(1, "ftstat_def_free(%s): failed.",ftsd->name); } if (ftio_close(&ftio) < 0) fterr_errx(1, "ftio_close(): failed"); if (debug > 0) { ftprof_end (&ftp, total_flows); ftprof_print(&ftp, argv[0], stderr); } ftstat_free(&ftstat); ftvar_free(&ftvar); return 0; } /* main */
void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; int rekeying = 0, max_fd; u_int nalloc = 0; u_int64_t rekey_timeout_ms = 0; debug("Entering interactive session for SSH2."); mysignal(SIGCHLD, sigchld_handler); child_terminated = 0; connection_in = packet_get_connection_in(); connection_out = packet_get_connection_out(); if (!use_privsep) { signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGQUIT, sigterm_handler); } notify_setup(); max_fd = MAX(connection_in, connection_out); max_fd = MAX(max_fd, notify_pipe[0]); server_init_dispatch(); for (;;) { process_buffered_input_packets(); rekeying = (xxx_kex != NULL && !xxx_kex->done); if (!rekeying && packet_not_very_much_data_to_write()) channel_output_poll(); if (options.rekey_interval > 0 && compat20 && !rekeying) rekey_timeout_ms = packet_get_rekey_timeout() * 1000; else rekey_timeout_ms = 0; wait_until_can_do_something(&readset, &writeset, &max_fd, &nalloc, rekey_timeout_ms); if (received_sigterm) { logit("Exiting on signal %d", (int)received_sigterm); /* Clean up sessions, utmp, etc. */ cleanup_exit(255); } collect_children(); if (!rekeying) { channel_after_select(readset, writeset); if (packet_need_rekeying()) { debug("need rekeying"); xxx_kex->done = 0; kex_send_kexinit(xxx_kex); } } process_input(readset); if (connection_closed) break; process_output(writeset); } collect_children(); free(readset); free(writeset); /* free all channels, no more reads and writes */ channel_free_all(); /* free remaining sessions, e.g. remove wtmp entries */ session_destroy_all(NULL); }
/* * Receive a file. */ static void recvtftp(struct testcase *test, struct formats *pf) { struct tftphdr *dp; struct tftphdr *ap; /* ack buffer */ unsigned short block = 0; int n, size; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif dp = w_init(); ap = (struct tftphdr *)ackbuf; do { timeout = 0; ap->th_opcode = htons((u_short)ACK); ap->th_block = htons((u_short)block); block++; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif send_ack: if (send(peer, ackbuf, 4, 0) != 4) { logmsg("write: fail\n"); goto abort; } write_behind(test, pf->f_convert); for ( ; ; ) { #ifdef HAVE_ALARM alarm(rexmtval); #endif n = recv(peer, dp, PKTSIZE, 0); #ifdef HAVE_ALARM alarm(0); #endif if (n < 0) { /* really? */ logmsg("read: fail\n"); goto abort; } dp->th_opcode = ntohs((u_short)dp->th_opcode); dp->th_block = ntohs((u_short)dp->th_block); if (dp->th_opcode == ERROR) goto abort; if (dp->th_opcode == DATA) { if (dp->th_block == block) { break; /* normal */ } /* Re-synchronize with the other side */ (void) synchnet(peer); if (dp->th_block == (block-1)) goto send_ack; /* rexmit */ } } size = writeit(test, &dp, n - 4, pf->f_convert); if (size != (n-4)) { /* ahem */ if (size < 0) nak(errno + 100); else nak(ENOSPACE); goto abort; } } while (size == SEGSIZE); write_behind(test, pf->f_convert); ap->th_opcode = htons((u_short)ACK); /* send the "final" ack */ ap->th_block = htons((u_short)(block)); (void) send(peer, ackbuf, 4, 0); #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, justquit); /* just quit on timeout */ alarm(rexmtval); #endif n = recv(peer, buf, sizeof (buf), 0); /* normally times out and quits */ #ifdef HAVE_ALARM alarm(0); #endif if (n >= 4 && /* if read some data */ dp->th_opcode == DATA && /* and got a data block */ block == dp->th_block) { /* then my last ack was lost */ (void) send(peer, ackbuf, 4, 0); /* resend final ack */ } abort: return; }