void command_line_handler (char *rl) { struct buffer *line_buffer = get_command_line_buffer (); struct ui *ui = current_ui; char *cmd; cmd = handle_line_of_input (line_buffer, rl, 1, "prompt"); if (cmd == (char *) EOF) { /* stdin closed. The connection with the terminal is gone. This happens at the end of a testsuite run, after Expect has hung up but GDB is still alive. In such a case, we just quit gdb killing the inferior program too. */ printf_unfiltered ("quit\n"); execute_command ("quit", 1); } else if (cmd == NULL) { /* We don't have a full line yet. Print an empty prompt. */ display_gdb_prompt (""); } else { ui->prompt_state = PROMPT_NEEDED; command_handler (cmd); if (ui->prompt_state != PROMPTED) display_gdb_prompt (0); } }
static int process_req_vendor(struct udc *udc, struct usb_ctrlrequest *ctrl) { if (ctrl->bRequest == 0x40) return command_handler(udc, ctrl); return -1; }
static inline void dpram_ipc_rx(struct dpram_link_device *dpld, u16 intr) { if (unlikely(INT_CMD_VALID(intr))) command_handler(dpld, intr); else non_command_handler(dpld, intr); }
void msg_event_handler( int fd, int msgid, int event ) { char buf[PACK_DATA_SIZE]; ssize_t n; // printf( "event 0x%03x for msg %d\n", event, msgid ); switch ( event ) { case MSG_EVT_ACCEPT_READY: if ( msg_accept( fd, msgid ) != 0 ) msg_set_read( fd, msgid ); // These are commands break; case MSG_EVT_READ_READY: msg_clr_read( fd, msgid ); n = msg_read( fd, msgid, buf, sizeof( buf ) ); if ( n <= 0 ) { cleanup_connection( msg_get_type( fd, msgid ) ); break; } if ( msg_get_type( fd, msgid ) < 0 ) { /* If the msgid is less than zero, it refers to a command and the message should not be routed to a file descriptor. */ // the entire command must fit inside one transport command_handler( fd, msgid, buf, n ); } else { zs_set_write( msg_get_type( fd, msgid ) ); /* if msgid is zero or greater it refers to a socket file descriptor that the message should be routed to. */ if ( zs_write( msg_get_type( fd, msgid ), buf, n ) == -1 ) cleanup_connection( msg_get_type( fd, msgid ) ); } break; case MSG_EVT_WRITE_READY: if ( msgid < 0 ) break; zs_set_read( msg_get_type( fd, msgid ) ); msg_clr_write( fd, msgid ); break; case MSG_SWITCH_EVT_IO_ERROR: //zclose( msg_switch->sockfd ); if ( website_get_by_sockfd( fd ) ) remove_website( fd ); else { for ( n = 0; n < FD_SETSIZE; n++ ) { if ( msg_exists( fd, n ) ) { if ( msg_get_type( fd, n ) > 0 ) cleanup_connection( msg_get_type( fd, n ) ); // else // msg_close( fd, n ); } } msg_switch_destroy( fd ); zs_close( fd ); } break; } }
static irqreturn_t dpram_irq_handler(int irq, void *data) { struct dpram_link_device *dpld = (struct dpram_link_device *)data; struct link_device *ld = (struct link_device *)&dpld->ld; u16 int2ap = 0; if (unlikely(ld->mode == LINK_MODE_OFFLINE)) return IRQ_HANDLED; if (dpram_wake_up(dpld) < 0) { log_dpram_status(dpld); trigger_force_cp_crash(dpld); return IRQ_HANDLED; } int2ap = recv_intr(dpld); if (unlikely(int2ap == INT_POWERSAFE_FAIL)) { mif_info("%s: int2ap == INT_POWERSAFE_FAIL\n", ld->name); goto exit; } else if (int2ap == 0x1234 || int2ap == 0xDBAB || int2ap == 0xABCD) { if (dpld->ext_op && dpld->ext_op->dload_cmd_handler) { dpld->ext_op->dload_cmd_handler(dpld, int2ap); goto exit; } } if (unlikely(EXT_UDL_CMD(int2ap))) { if (likely(EXT_INT_VALID(int2ap))) { if (UDL_CMD_VALID(int2ap)) udl_command_handler(dpld, int2ap); else if (EXT_CMD_VALID(int2ap)) ext_command_handler(dpld, int2ap); else mif_info("%s: ERR! invalid intr 0x%04X\n", ld->name, int2ap); } else { mif_info("%s: ERR! invalid intr 0x%04X\n", ld->name, int2ap); } } else { if (likely(INT_VALID(int2ap))) { if (unlikely(INT_CMD_VALID(int2ap))) command_handler(dpld, int2ap); else non_command_handler(dpld, int2ap); } else { mif_info("%s: ERR! invalid intr 0x%04X\n", ld->name, int2ap); } } exit: clear_intr(dpld); dpram_allow_sleep(dpld); return IRQ_HANDLED; }
// handle one socket connection int client_handler(int connfd) { int r = prompt(connfd); if(!r) return CLIENT_END; if(r != COMMAND_HANDLED) { command_handler(connfd); } print_prompt_sign(connfd); return CLIENT_CONT; }
static void * _server_socket_command_handler (void *arg) { thread_list_t entry = (thread_list_t)arg; accept_command_t clean = ACCEPT_THREAD_CLEAN; command_handler (entry->fd, entry->config); entry->stopped = 1; if (write (s_fd_accept_terminate[1], &clean, sizeof (clean)) == -1) { common_log (LOG_FATAL, "write failed"); } return NULL; }
/* ------------- entering return in command prompt */ G_MODULE_EXPORT void on_textEntry_Command_activate( GtkObject *object, gpointer user_data) { char cmd_buffer[256]; // copy it in strncpy(cmd_buffer, gtk_entry_get_text(GTK_ENTRY(object)), ARRAY_SIZE(cmd_buffer)-1); cmd_buffer[ARRAY_SIZE(cmd_buffer)-1]= 0; // clear it out.. gtk_entry_set_text(GTK_ENTRY(object), ""); /*only do something if a command was entered. Don't do anything if user just hit return*/ if(strcspn(cmd_buffer," ,\n\t")) { /* remember it */ record_command(cmd_buffer); /* call cmd multiplexor */ command_handler(cmd_buffer); } }
int main() { int flags = fcntl(0, F_GETFL, 0); fcntl(0, F_SETFL, flags | O_NONBLOCK); char buffer[1024]; getcwd(directory, 1024); List* l = list_constructor(); command_t command; reset_command(&command); prompt(); while(1) { if(read(0, buffer, 1023) > 0) { // read the command into the struct read_command(buffer, &command); // parse the command for background execution, change directory, or file redirection parse_command(&command); /* call the command handler. this will execute the command. handles both background and non-background */ int pid = command_handler(&command, l); if(pid == 0) { return 0; } // reset the command. reset_command(&command); } // check for background commands and remove them from the wait list. check_background_commands(l); } return 0; }
/* NOTE: 1999-04-30 This is the asynchronous version of the command_line_input function; command_line_input will become obsolete once we use the event loop as the default mechanism in GDB. */ static void command_line_handler (char *rl) { static char *linebuffer = 0; static unsigned linelength = 0; char *p; char *p1; char *nline; int repeat = (instream == stdin); if (annotation_level > 1 && instream == stdin) { printf_unfiltered (("\n\032\032post-")); puts_unfiltered (async_annotation_suffix); printf_unfiltered (("\n")); } if (linebuffer == 0) { linelength = 80; linebuffer = (char *) xmalloc (linelength); } p = linebuffer; if (more_to_come) { strcpy (linebuffer, readline_input_state.linebuffer); p = readline_input_state.linebuffer_ptr; xfree (readline_input_state.linebuffer); more_to_come = 0; } #ifdef STOP_SIGNAL if (job_control) signal (STOP_SIGNAL, handle_stop_sig); #endif /* Make sure that all output has been output. Some machines may let you get away with leaving out some of the gdb_flush, but not all. */ wrap_here (""); gdb_flush (gdb_stdout); gdb_flush (gdb_stderr); if (source_file_name != NULL) ++source_line_number; /* If we are in this case, then command_handler will call quit and exit from gdb. */ if (!rl || rl == (char *) EOF) { command_handler (0); return; /* Lint. */ } if (strlen (rl) + 1 + (p - linebuffer) > linelength) { linelength = strlen (rl) + 1 + (p - linebuffer); nline = (char *) xrealloc (linebuffer, linelength); p += nline - linebuffer; linebuffer = nline; } p1 = rl; /* Copy line. Don't copy null at end. (Leaves line alone if this was just a newline). */ while (*p1) *p++ = *p1++; xfree (rl); /* Allocated in readline. */ if (p > linebuffer && *(p - 1) == '\\') { *p = '\0'; p--; /* Put on top of '\'. */ readline_input_state.linebuffer = xstrdup (linebuffer); readline_input_state.linebuffer_ptr = p; /* We will not invoke a execute_command if there is more input expected to complete the command. So, we need to print an empty prompt here. */ more_to_come = 1; display_gdb_prompt (""); return; } #ifdef STOP_SIGNAL if (job_control) signal (STOP_SIGNAL, SIG_DFL); #endif #define SERVER_COMMAND_LENGTH 7 server_command = (p - linebuffer > SERVER_COMMAND_LENGTH) && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0; if (server_command) { /* Note that we don't set `line'. Between this and the check in dont_repeat, this insures that repeating will still do the right thing. */ *p = '\0'; command_handler (linebuffer + SERVER_COMMAND_LENGTH); display_gdb_prompt (0); return; } /* Do history expansion if that is wished. */ if (history_expansion_p && instream == stdin && ISATTY (instream)) { char *history_value; int expanded; *p = '\0'; /* Insert null now. */ expanded = history_expand (linebuffer, &history_value); if (expanded) { /* Print the changes. */ printf_unfiltered ("%s\n", history_value); /* If there was an error, call this function again. */ if (expanded < 0) { xfree (history_value); return; } if (strlen (history_value) > linelength) { linelength = strlen (history_value) + 1; linebuffer = (char *) xrealloc (linebuffer, linelength); } strcpy (linebuffer, history_value); p = linebuffer + strlen (linebuffer); } xfree (history_value); } /* If we just got an empty line, and that is supposed to repeat the previous command, return the value in the global buffer. */ if (repeat && p == linebuffer && *p != '\\') { command_handler (saved_command_line); display_gdb_prompt (0); return; } for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++); if (repeat && !*p1) { command_handler (saved_command_line); display_gdb_prompt (0); return; } *p = 0; /* Add line to history if appropriate. */ if (instream == stdin && ISATTY (stdin) && *linebuffer) add_history (linebuffer); /* Note: lines consisting solely of comments are added to the command history. This is useful when you type a command, and then realize you don't want to execute it quite yet. You can comment out the command and then later fetch it from the value history and remove the '#'. The kill ring is probably better, but some people are in the habit of commenting things out. */ if (*p1 == '#') *p1 = '\0'; /* Found a comment. */ /* Save into global buffer if appropriate. */ if (repeat) { if (linelength > saved_command_line_size) { saved_command_line = xrealloc (saved_command_line, linelength); saved_command_line_size = linelength; } strcpy (saved_command_line, linebuffer); if (!more_to_come) { command_handler (saved_command_line); display_gdb_prompt (0); } return; } command_handler (linebuffer); display_gdb_prompt (0); return; }
/******************************************************************* * MAIN() *******************************************************************/ int main(void) { long lEEPROMRetStatus; uint16_t i=0; uint8_t halted_latch = 0; // Set the clocking to run at 80 MHz from the PLL. // (Well we were at 80MHz with SYSCTL_SYSDIV_2_5 but according to the errata you can't // write to FLASH at frequencies greater than 50MHz so I slowed it down. I supposed we // could slow the clock down when writing to FLASH but then we need to find out how long // it takes for the clock to stabilize. This is on at the bottom of my list of things to do // for now) SysCtlClockSet(SYSCTL_SYSDIV_4_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN); // Initialize the device pinout. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); // Enable processor interrupts. IntMasterEnable(); // Setup the UART's my_uart_0_init(115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // command_handler_init overwrites the baud rate. We still need to configure the pins though my_uart_1_init(38400, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); // Enable the command handler command_handler_init(); // We set the baud in here // Start the timers my_timer0_init(); my_timer1_init(); i2c_init(); motor_init(); qei_init(); gyro_init(); accel_init(); led_init(); //rc_radio_init(); //setupBluetooth(); // Initialize the EEPROM emulation region. lEEPROMRetStatus = SoftEEPROMInit(EEPROM_START_ADDR, EEPROM_END_ADDR, EEPROM_PAGE_SIZE); if(lEEPROMRetStatus != 0) UART0Send("EEprom ERROR!\n", 14); #if 0 // If ever we wanted to write some parameters to FLASH without the HMI // we could do it here. SoftEEPROMWriteDouble(kP_ID, 10.00); SoftEEPROMWriteDouble(kI_ID, 10.00); SoftEEPROMWriteDouble(kD_ID, 10.00); SoftEEPROMWriteDouble(ANG_ID, 0.0); SoftEEPROMWriteDouble(COMPC_ID, 0.99); #endif kP = SoftEEPROMReadDouble(kP_ID); kI = SoftEEPROMReadDouble(kI_ID); kD = SoftEEPROMReadDouble(kD_ID); commanded_ang = zero_ang = SoftEEPROMReadDouble(ANG_ID); COMP_C = SoftEEPROMReadDouble(COMPC_ID); pid_init(kP, kI, kD, &pid_ang); motor_controller_init(20, 100, 10, &mot_left); motor_controller_init(20, 100, 10, &mot_right); //pid_init(0.0, 0.0, 0.0, &pid_pos_left); //pid_init(0.0, 0.0, 0.0, &pid_pos_right); //UART0Send("Hello World!\n", 13); // Tell the HMI what the initial parameters are. print_params(1); while(1) { delta_t = myTimerValueGet(); myTimerZero(); sum_delta_t += delta_t; // Read our sensors accel_get_xyz_cal(&accel_x, &accel_y, &accel_z, true); gyro_get_y_cal(&gyro_y, false); // Calculate the pitch angle with the accelerometer only R = sqrt(pow(accel_x, 2) + pow(accel_z, 2)); accel_pitch_ang = (acos(accel_z / R)*(RAD_TO_DEG)) - 90.0 - zero_ang; //accel_pitch_ang = (double)((atan2(accel_x, -accel_z))*RAD_TO_DEG - 90.0); gyro_pitch_ang += (double)gyro_y*g_gyroScale*CONV_TO_SEC(delta_t); // Kalman filter //filtered_ang = kalman((double)accel_pitch_ang, ((double)gyro_y)*g_gyroScale, CONV_TO_SEC(delta_t)); filtered_ang = (COMP_C*(filtered_ang+((double)gyro_y*g_gyroScale*CONV_TO_SEC(delta_t)))) + ((1.0-COMP_C)*(double)accel_pitch_ang); // Skip the rest of the process until the angle stabilizes if(i < 250) { i++; continue; } // Tell the HMI what's going on every 100ms if(sum_delta_t >= 1000) { print_update(1); print_debug(0); //print_control_surfaces(0); led_toggle(); //print_angle(); sum_delta_t = 0; } // See if the HMI has anything to say command_handler(); //continue; // If we are leaning more than +/- FALL_ANG deg off center it's hopeless. // Turn off the motors in hopes of some damage control if( abs(filtered_ang) > FALL_ANG ) { if(halted_latch) continue; stop_motors(); halted_latch = 1; continue; } halted_latch = 0; motor_val = pid_controller(calc_commanded_angle(0), filtered_ang, delta_t, &pid_ang); motor_left = motor_right = motor_val; drive_motors(motor_left*left_mot_gain, motor_right*right_mot_gain); } }
int main(void) { // init all needed services cli(); timer_init(); USART_init(); ADC_init(); sei(); // set up enable port ENA_DDR = /*(1 << ENA_LED) |*/ (1 << ENA_PIN); // ENA_PORT = (1 << ENA_LED); // init condition is receiving driverReceive(); // string, char and ascii buffers for serial comm. uint8_t read_buf = 0x00, ascii_bufh = 0x00, ascii_bufl = 0x00; char str_buf[10]; // send own address on startup HexToAscii(str_buf, 3, own_addr); sendString(str_buf); sendString(EOM); while(1) { // check if there is something to be read (non blocking...) if ( USART_dataAvaliable() ){ read_buf = 0x00; read_buf = USART_readByte(); switch(MPPC_status){ /* no start delimiter, awaits start delimiter */ case IDLE: if (read_buf == '<'){ MPPC_status = LISTENING; } else { MPPC_status = IDLE; sleep_ms(2); } break; /* received a start delimiter, awaits adress */ case LISTENING: // check wether there are characters or ASCII numbers beeing send if ( ((read_buf >= '0') && (read_buf <= '9')) || ((read_buf >= 'A') && (read_buf <= 'F')) ) { // a ASCII number has been sent, we need another digit str_buf[0] = read_buf; str_buf[1] = USART_receiveByte(); // convert both ascii numbers into a 'real' hex number read_buf = AsciiToHex(str_buf, 2); HexToAscii(str_buf, 3, read_buf); } else { // in this stage we need an address; if there are no numbers beeing sent, we are not interested anymore! MPPC_status = IDLE; break; } // We received an address, converted it to hex and now want to check, if it is our's if (read_buf == own_addr){ MPPC_status = ADDRESSED; // SEL_LED on -> module has been selected + echo sendString(str_buf); // ENA_PORT&= ~(1 << ENA_LED); // echo in ASCII } else { MPPC_status = IDLE; } break; /* received it's own address, awaits command */ case ADDRESSED: if (read_buf == '>'){ // stop delimiter MPPC_status = IDLE; // ENA_PORT |= (1 << ENA_LED); // SEL_LED off -> module has been deselected } else { command_handler(read_buf); // yet another switch/case stucture... } break; } // end switch } // end if // apply bias voltages setBiasVoltage(); } }
void key_handler() { char c, i; while(true) { draw(); c = G_wait_key(); i = c - 48; //Convert ASCII character codes to digits if (i > 0 && i <= num_objs) { printf("Switching control to shape %d\n", i); obj = &objs[i-1]; } switch (c) { case 84: //Down arrow key object3d_rotate(obj, -M_PI/60, 0, 0); break; case 82: //Up arrow key object3d_rotate(obj, M_PI/60, 0, 0); break; case 81: //Left arrow key object3d_rotate(obj, 0, M_PI/60, 0); break; case 83: //Right arrow key object3d_rotate(obj, 0, -M_PI/60, 0); break; case 'w': transform_object3d(obj, y_plus); break; case 'a': transform_object3d(obj, x_minus); break; case 's': transform_object3d(obj, y_minus); break; case 'd': transform_object3d(obj, x_plus); break; case 'q': transform_object3d(obj, z_minus); break; case 'e': transform_object3d(obj, z_plus); break; case ']': object3d_scale(obj, 1.1, 1.1, 1.1); break; case '[': object3d_scale(obj, 1.0/1.1, 1.0/1.1, 1.0/1.1); break; case '=': //viewdistance += .2; break; case '-': //viewdistance -= .2; break; case '+': //Smaller FOV zooms in fov -= M_PI/36; break; case '_': //Larger FOV zooms out fov += M_PI/36; break; case 32: command_handler(); break; } } }
int main (int argc, char *argv[]) { enum { OPT_SERVER, OPT_MUTLI_SERVER, OPT_DAEMON, OPT_VERBOSE, OPT_QUIET, OPT_SH, OPT_CSH, OPT_OPTIONS, OPT_NO_DETACH, OPT_LOG_FILE, OPT_VERSION, OPT_HELP }; static struct option long_options[] = { { "server", no_argument, NULL, OPT_SERVER }, { "multi-server", no_argument, NULL, OPT_MUTLI_SERVER }, { "daemon", no_argument, NULL, OPT_DAEMON }, { "verbose", no_argument, NULL, OPT_VERBOSE }, { "quiet", no_argument, NULL, OPT_QUIET }, { "sh", no_argument, NULL, OPT_SH }, { "csh", no_argument, NULL, OPT_CSH }, { "options", required_argument, NULL, OPT_OPTIONS }, { "no-detach", no_argument, NULL, OPT_NO_DETACH }, { "log-file", required_argument, NULL, OPT_LOG_FILE }, { "version", no_argument, NULL, OPT_VERSION }, { "help", no_argument, NULL, OPT_HELP }, { NULL, 0, NULL, 0 } }; int long_options_ret; int base_argc = 1; int usage_ok = 1; enum { RUN_MODE_NONE, RUN_MODE_SERVER, RUN_MODE_MULTI_SERVER, RUN_MODE_DAEMON } run_mode = RUN_MODE_NONE; int env_is_csh = 0; int log_verbose = 0; int log_quiet = 0; int no_detach = 0; char *config_file = NULL; char *log_file = NULL; char *home_dir = NULL; int have_at_least_one_provider=0; FILE *fp_log = NULL; int i; CK_RV rv; dconfig_data_t config; const char * CONFIG_SUFFIX = ".conf"; char *default_config_file = NULL; #if !defined(HAVE_W32_SYSTEM) s_parent_pid = getpid (); #endif if ((default_config_file = (char *)malloc (strlen (PACKAGE)+strlen (CONFIG_SUFFIX)+1)) == NULL) { common_log (LOG_FATAL, "malloc failed"); } sprintf (default_config_file, "%s%s", PACKAGE, CONFIG_SUFFIX); common_set_log_stream (stderr); while ((long_options_ret = getopt_long (argc, argv, "vqsc", long_options, NULL)) != -1) { base_argc++; switch (long_options_ret) { case OPT_SERVER: run_mode = RUN_MODE_SERVER; break; case OPT_MUTLI_SERVER: run_mode = RUN_MODE_MULTI_SERVER; break; case OPT_DAEMON: run_mode = RUN_MODE_DAEMON; break; case OPT_VERBOSE: case 'v': log_verbose = 1; break; case OPT_QUIET: case 'q': log_quiet = 1; break; case OPT_SH: case 's': break; case OPT_CSH: case 'c': env_is_csh = 1; break; case OPT_OPTIONS: base_argc++; config_file = strdup (optarg); break; case OPT_NO_DETACH: no_detach = 1; break; case OPT_LOG_FILE: base_argc++; log_file = strdup (optarg); break; case OPT_VERSION: printf ( "%s %s\n" "\n" "Copyright (c) 2006-2007 Zeljko Vrba <*****@*****.**>\n" "Copyright (c) 2006-2011 Alon Bar-Lev <*****@*****.**>\n" "\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", PACKAGE, PACKAGE_VERSION ); exit (1); break; case OPT_HELP: usage_ok = 0; break; default: usage_ok = 0; break; } } if (base_argc < argc) { if (!strcmp (argv[base_argc], "--")) { base_argc++; } } if (!usage_ok) { usage (argv[0]); } if (run_mode == RUN_MODE_NONE) { common_log (LOG_FATAL, "please use the option `--daemon' to run the program in the background"); } #if defined(HAVE_W32_SYSTEM) if (run_mode == RUN_MODE_DAEMON) { common_log (LOG_FATAL, "daemon mode is not supported"); } #endif home_dir = get_home_dir (); if (config_file == NULL) { if ((config_file = (char *)malloc (strlen (home_dir) + strlen (default_config_file)+2)) == NULL) { common_log (LOG_FATAL, "malloc failed"); } sprintf (config_file, "%s%c%s", home_dir, CONFIG_PATH_SEPARATOR, default_config_file); } if ( !dconfig_read (config_file, &config) && !dconfig_read (CONFIG_SYSTEM_CONFIG, &config) ) { common_log (LOG_FATAL, "Cannot open configuration file"); } if (log_file != NULL) { if (config.log_file != NULL) { free (config.log_file); } if ((config.log_file = strdup (log_file)) == NULL) { common_log (LOG_FATAL, "strdup failed"); } } if (log_verbose) { config.verbose = 1; } #if !defined(HAVE_W32_SYSTEM) signal (SIGPIPE, SIG_IGN); signal (SIGINT, on_signal); signal (SIGTERM, on_signal); signal (SIGABRT, on_signal); signal (SIGHUP, on_signal); #endif if (log_file != NULL) { if (strcmp (log_file, "stderr")) { if ((fp_log = fopen (log_file, "a")) != NULL) { common_set_log_stream (fp_log); } } } else if (config.log_file != NULL) { if (strcmp (config.log_file, "stderr")) { if ((fp_log = fopen (config.log_file, "a")) != NULL) { common_set_log_stream (fp_log); } } } if (config.debug) { common_log (LOG_DEBUG, "version: %s", PACKAGE_VERSION); dconfig_print (&config); common_log (LOG_DEBUG, "run_mode: %d", run_mode); common_log (LOG_DEBUG, "crypto: %s", #if defined(ENABLE_OPENSSL) "openssl" #elif defined(ENABLE_GNUTLS) "gnutls" #else "invalid" #endif ); } #if !defined(HAVE_W32_SYSTEM) if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) { server_socket_create_name (); } /* * fork before doing PKCS#11 stuff * some providers don't behave well */ if (run_mode == RUN_MODE_DAEMON) { pid_t pid; pid = fork (); if (pid == -1) { common_log (LOG_FATAL, "fork failed"); } if (pid != 0) { static const char *key = "SCDAEMON_INFO"; char env[1024]; snprintf (env, sizeof (env), "%s:%lu:1", s_socket_name, (unsigned long)pid); if (argc - base_argc > 0) { setenv(key, env, 1); execvp (argv[base_argc], &(argv[base_argc])); kill (pid, SIGTERM); exit (1); } else { if (env_is_csh) { *strchr (env, '=') = ' '; printf ("setenv %s %s\n", key, env); } else { printf ("%s=%s; export %s\n", key, env, key); } exit (0); } } if (!no_detach) { int i; for (i=0;i<3;i++) { if (fileno (common_get_log_stream ()) != i) { close (i); } } if (setsid () == -1) { common_log (LOG_FATAL, "setsid failed"); } } if (chdir ("/") == -1) { common_log (LOG_FATAL, "chdir failed"); } if (argc - base_argc > 0) { struct sigaction sa; memset (&sa, 0, sizeof (sa)); sigemptyset (&sa.sa_mask); #if defined(SA_INTERRUPT) sa.sa_flags |= SA_INTERRUPT; #endif sa.sa_handler = on_alarm; sigaction (SIGALRM, &sa, NULL); alarm (10); } } #endif /* HAVE_W32_SYSTEM */ assuan_set_assuan_log_prefix (PACKAGE); assuan_set_assuan_log_stream (common_get_log_stream ()); #if defined(USE_GNUTLS) if (gnutls_global_init () != GNUTLS_E_SUCCESS) { common_log (LOG_FATAL, "Cannot initialize gnutls"); } #endif if ((rv = pkcs11h_initialize ()) != CKR_OK) { common_log (LOG_FATAL, "Cannot initialize PKCS#11: %s", pkcs11h_getMessage (rv)); } pkcs11h_setLogLevel (config.verbose ? PKCS11H_LOG_DEBUG2 : PKCS11H_LOG_INFO); pkcs11h_setLogHook (pkcs11_log_hook, NULL); pkcs11h_setTokenPromptHook (pkcs11_token_prompt_hook, NULL); pkcs11h_setPINPromptHook (pkcs11_pin_prompt_hook, NULL); pkcs11h_setProtectedAuthentication (TRUE); for (i=0;i<DCONFIG_MAX_PROVIDERS;i++) { if ( config.providers[i].name != NULL && config.providers[i].library != NULL ) { if ( (rv = pkcs11h_addProvider ( config.providers[i].name, config.providers[i].library, config.providers[i].allow_protected, config.providers[i].private_mask, PKCS11H_SLOTEVENT_METHOD_POLL, 0, config.providers[i].cert_is_private )) != CKR_OK ) { common_log (LOG_WARNING, "Cannot add PKCS#11 provider '%s': %ld-'%s'", config.providers[i].name, rv, pkcs11h_getMessage (rv)); } else { have_at_least_one_provider = 1; } } } if (!have_at_least_one_provider) { common_log (LOG_FATAL, "Could not load any provider"); } #if defined(HAVE_W32_SYSTEM) command_handler (-1, &config); #else { pthread_t accept_thread = 0; int accept_socket = -1; if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) { accept_socket = server_socket_create (); server_socket_accept (accept_socket, &accept_thread, &config); } if (run_mode == RUN_MODE_DAEMON) { /* * Emulate assuan behavior */ int fds[2]; char c; if (pipe (fds)==-1) { common_log (LOG_FATAL, "Could not create pipe"); } close (0); dup2 (fds[0], 0); close (fds[0]); while (read (0, &c, 1) == -1 && errno == EINTR); close (fds[1]); } else { command_handler (-1, &config); } if (run_mode == RUN_MODE_DAEMON || run_mode == RUN_MODE_MULTI_SERVER) { server_socket_accept_terminate (accept_thread); server_socket_close (accept_socket); } } #endif pkcs11h_terminate (); #if defined(USE_GNUTLS) gnutls_global_deinit (); #endif dconfig_free (&config); if (log_file != NULL) { free (log_file); log_file = NULL; } if (config_file != NULL) { free (config_file); config_file = NULL; } if (default_config_file != NULL) { free (default_config_file); default_config_file = NULL; } if (home_dir != NULL) { free (home_dir); home_dir = NULL; } if (fp_log != NULL) { fclose (fp_log); fp_log = NULL; } return 0; }