//{{{ int main(int argc,char** argv) int main(int argc,char** argv) { //get_config(); format_msg(0);//初次运行时获取天气 get_batt();// 初次运行时获取电量 get_cpu();//cpu get_mem();//mem get_net();//net get_temp();//temperature get_mailchk();//2014-4-2添加,邮件检查的显示。 disp_msg(); exit(0); }//}}}
static void send_one_byte ( const uint8_t data ) { assert( connection_socket != -1 ); try { write_loop( connection_socket, &data, sizeof(data) ); } catch ( const std::exception & e ) { throw std::runtime_error( format_msg( "Error writing to the JTAG socket: %s", e.what() ) ); } }
static void collect_cpu_stop_reason ( const bool stopped_via_edis ) { assert( rsp.is_target_running == false ); uint32_t drrval; dbg_cpu0_read_spr_e( SPR_DRR, &drrval ); // Read the DRR, find out why the CPU stopped. // Note that the current OR10 implementation only supports the "trap" reason. assert( drrval == 0 || drrval == SPR_DRR_TE ); int sigval; // GDB signal equivalent to exception switch ( drrval ) { case SPR_DRR_RSTE: sigval = TARGET_SIGNAL_PWR; break; case SPR_DRR_BUSEE: sigval = TARGET_SIGNAL_BUS; break; case SPR_DRR_DPFE: sigval = TARGET_SIGNAL_SEGV; break; case SPR_DRR_IPFE: sigval = TARGET_SIGNAL_SEGV; break; case SPR_DRR_TTE: sigval = TARGET_SIGNAL_ALRM; break; case SPR_DRR_AE: sigval = TARGET_SIGNAL_BUS; break; case SPR_DRR_IIE: sigval = TARGET_SIGNAL_ILL; break; case SPR_DRR_IE: sigval = TARGET_SIGNAL_INT; break; case SPR_DRR_DME: sigval = TARGET_SIGNAL_SEGV; break; case SPR_DRR_IME: sigval = TARGET_SIGNAL_SEGV; break; case SPR_DRR_RE: sigval = TARGET_SIGNAL_FPE; break; case SPR_DRR_SCE: sigval = TARGET_SIGNAL_USR2; break; case SPR_DRR_FPE: sigval = TARGET_SIGNAL_FPE; break; case SPR_DRR_TE: sigval = TARGET_SIGNAL_TRAP; break; // In the current OR10 hardware implementation, a single-step does not raise a TRAP, // so the DRR reads back 0. GDB expects a TRAP signal, so convert it here. // If the CPU was not in single-step mode, we have lost the last stop reason, // a TRAP should be alright too. case 0: assert( rsp.is_in_single_step_mode || stopped_via_edis ); sigval = TARGET_SIGNAL_TRAP; break; default: assert( false ); // Should actually never happen. throw std::runtime_error( format_msg( "The CPU SPR DDR register contains the illegal value 0x%08X.", drrval ) ); } rsp.sigval = sigval; for ( unsigned i = 0; i < rsp.watchpoint_count; ++i ) { dbg_cpu0_read_spr_e( SPR_DVR(i), &rsp.watchpoint_addr[ i ] ); // printf( "Watchpoint addr: 0x%08X\n", rsp.watchpoint_addr[ i ] ); } }
static void rsp_write_reg ( const rsp_buf * const buf ) { unsigned int regnum; char valstr[9]; // Allow for EOS on the string // Break out the fields from the data. if ( 2 != sscanf (buf->data, "P%x=%8s", ®num, valstr ) ) { throw std::runtime_error( "Illegal write register packet." ); } // Set the relevant register. Must translate between GDB register numbering and hardware reg. numbers. uint16_t spr_number; bool ignore = false; switch ( regnum ) { case PPC_REGNUM: // The OR10 CPU does not support this register, any writes to it are ignored here. // GDB should not try to read and write this register any more. spr_number = (uint16_t) -1; ignore = true; break; case NPC_REGNUM: spr_number = SPR_NPC; break; case SR_REGNUM: spr_number = SPR_SR; break; default: if ( regnum >= 0 && regnum < MAX_GPRS ) { spr_number = SPR_GPR_BASE + regnum; break; } throw std::runtime_error( format_msg( "Unknown register number %d processing a write register packet.", regnum ) ); } if ( !ignore ) { const uint32_t new_val = parse_reg_32_from_hex( valstr ); dbg_cpu0_write_spr_e( spr_number, new_val ); } send_ok_packet( rsp.client_fd ); }
int main ( int argc, char *argv[] ) { std::string exit_msg_prefix; try { exit_msg_prefix = format_msg( "Error running \"%s\": ", argv[0] ); return main_2( argc, argv ); } catch ( const std::exception & e ) { fprintf( stderr, "%s%s\n", exit_msg_prefix.c_str(), e.what() ); return 1; } }
static void rsp_write_mem ( const rsp_buf * const buf ) { unsigned int addr; int len; assert( buf->data[0] == 'M' ); if ( 2 != sscanf( buf->data, "M%x,%x:", &addr, &len ) ) { throw std::runtime_error( "Illegal write memory packet." ); } // Find the start of the data and check there is the amount we expect. const char * const symdat = ((const char *)memchr( buf->data, ':', GDB_BUF_MAX ) ) + 1; const int datlen = buf->len - (symdat - buf->data); // Sanity check. if ( len * 2 != datlen ) { throw std::runtime_error( format_msg( "Illegal write memory packet: Write of %d data hex digits requested, but %d digits were supplied.", len * 2, datlen ) ); } // Write the bytes to memory. // Put all the data into a single buffer, so it can be burst-written via JTAG. // One burst is much faster than many single-byte transactions. // NOTE: We don't support burst data accesses any more, but that may change in the future. std::vector< uint8_t > data; for ( int off = 0; off < len; off++ ) { const unsigned char nyb1 = parse_hex_digit( symdat[ off * 2 ] ); const unsigned char nyb2 = parse_hex_digit( symdat[ off * 2 + 1 ] ); data.push_back( (nyb1 << 4) | nyb2 ); } const bool error_bit = dbg_cpu0_write_mem( addr, len, &data ); if ( error_bit ) put_str_packet( rsp.client_fd, STD_ERROR_CODE ); else send_ok_packet( rsp.client_fd ); }
static int cable_vpi_init ( void ) { assert( connection_socket < 0 ); connection_socket = socket( PF_INET, SOCK_STREAM, 0 ); if ( connection_socket < 0 ) { throw std::runtime_error( format_errno_msg( errno, "Cannot create TCP socket: " ) ); } const hostent * const he = gethostbyname( remote_hostname.c_str() ); if ( he == NULL ) { throw std::runtime_error( format_msg( "Cannot resolve host name \"%s\".", remote_hostname.c_str() ) ); } struct sockaddr_in addr; memset( &addr, 0, sizeof(addr) ); addr.sin_family = AF_INET; addr.sin_port = htons(tcp_port); addr.sin_addr = *((struct in_addr *)he->h_addr); const std::string ip_addr_txt = ip_address_to_text( &addr.sin_addr ); printf( "Connecting to simulated JTAG at %s (IP addr %s) on TCP port %d... ", remote_hostname.c_str(), ip_addr_txt.c_str(), tcp_port ); const int connect_res = connect( connection_socket, (struct sockaddr *)&addr, sizeof(addr) ); if ( connect_res != 0 ) { const int saved_errno = errno; printf( "\n" ); throw std::runtime_error( format_errno_msg( saved_errno, "Error connecting to simulated JTAG at %s (IP addr %s) on TCP port %d: ", remote_hostname.c_str(), ip_addr_txt.c_str(), tcp_port ) ); } printf( "OK\n" ); return APP_ERR_NONE; }
static uint8_t receive_one_byte ( void ) { assert( connection_socket != -1 ); try { bool end_of_file; const uint8_t c = read_one_byte( connection_socket, &end_of_file ); if ( end_of_file ) throw std::runtime_error( "The remote server closed the connection." ); return c; } catch ( const std::exception & e ) { throw std::runtime_error( format_msg( "Error reading from the JTAG socket: %s", e.what() ) ); } }
static void rsp_pass_through_command ( const rsp_buf * const buf, const int cmd_str_pos ) { static const std::string HELP_PREFIX( "help" ); static const std::string READSPR_PREFIX ( "readspr" ); static const std::string WRITESPR_PREFIX( "writespr" ); static const std::string RESET_PREFIX( "reset" ); try { // The actual command follows the "qRcmd," RSP request in ASCII encoded in hex. std::string cmd = hex2ascii( &(buf->data[ cmd_str_pos ]) ); ltrim( &cmd ); rtrim( &cmd ); if ( cmd.empty() ) throw std::runtime_error( "No target-specific command specified." ); // printf( "Monitor cmd: %s\n", cmd.c_str() ); if ( str_remove_prefix( &cmd, &HELP_PREFIX ) ) { remove_cmd_separator( &cmd ); if ( ! cmd.empty() ) { throw std::runtime_error( "Error parsing the target-specific 'help' command: this command does not take any arguments." ); } std::string help_text = "\nAvailable target-specific commands:\n\n"; help_text += "- monitor help\n"; help_text += " Displays this help text.\n"; help_text += "\n"; help_text += "- monitor readspr <16-bit Special Purpose Register number in hex>\n"; help_text += " The register value is printed in hex.\n"; help_text += " This example reads the Debug Stop Register (DSR), whose number is\n"; help_text += " (6 << 11) [0x3000] + 20 = 0x3014:\n"; help_text += " monitor readspr 3014\n"; help_text += "\n"; help_text += "- monitor writespr <register number in hex> <register value in hex>\n"; help_text += "\n"; help_text += "- monitor reset\n"; help_text += " Resets the CPU.\n"; help_text += "\n"; send_pass_through_command_text_reply( rsp.client_fd, help_text.c_str() ); } else if ( str_remove_prefix( &cmd, &READSPR_PREFIX ) ) { remove_cmd_separator( &cmd ); unsigned int regno; // Parse and return error if we fail. if ( 1 != sscanf( cmd.c_str(), "%x", ®no ) ) { throw std::runtime_error( "Error parsing the target-specific 'readspr' command." ); } if ( regno >= MAX_SPRS ) { throw std::runtime_error( format_msg( "Error parsing the target-specific 'readspr' command: SPR number %u is out of range.", regno ) ); } uint32_t reg_val; dbg_cpu0_read_spr_e( uint16_t( regno ), ®_val ); const std::string reply_str = format_msg( "%08x\n", reg_val ); send_pass_through_command_text_reply( rsp.client_fd, reply_str.c_str() ); } else if ( str_remove_prefix( &cmd, &WRITESPR_PREFIX ) ) { remove_cmd_separator( &cmd ); unsigned int regno; unsigned long int val; if ( 2 != sscanf( cmd.c_str(), "%x %lx", ®no, &val ) ) { throw std::runtime_error( "Error parsing the target-specific 'writespr' command." ); } if ( regno >= MAX_SPRS ) { throw std::runtime_error( format_msg( "Error parsing the target-specific 'writespr' command: SPR number %u is out of range.", regno ) ); } dbg_cpu0_write_spr_e( uint16_t( regno ), val ); send_ok_packet( rsp.client_fd ); } else if ( str_remove_prefix( &cmd, &RESET_PREFIX ) ) { remove_cmd_separator( &cmd ); if ( ! cmd.empty() ) { throw std::runtime_error( "Error parsing the target-specific 'reset' command: this command does not take any arguments." ); } // In order to save FPGA resources, there is no reset signal or command in the Debug Unit. // We reset the CPU here by manually writing all necessary SPRs. const uint32_t RESET_SPR_SR = 0x8001; // See the RESET_SPR_SR constant in the CPU Verilog source code. const uint32_t RESET_VECTOR = 0x0100; // See the RESET_VECTOR constant in the CPU Verilog source code. dbg_cpu0_write_spr_e( SPR_SR , RESET_SPR_SR ); dbg_cpu0_write_spr_e( SPR_NPC, RESET_VECTOR ); dbg_cpu0_write_spr_e( SPR_EPCR_BASE, 0 ); dbg_cpu0_write_spr_e( SPR_EEAR_BASE, 0 ); dbg_cpu0_write_spr_e( SPR_ESR_BASE, 0 ); // The CPU uses another initial value for the GPRs, namely 0x12345678, which is fine. // According to the OpenRISC specification, it is not necessary to initialise these registers. const uint32_t INITIAL_GPR_VALUE = 0xABCDEF01; for ( int i = 0; i < MAX_GPRS; ++i ) { dbg_cpu0_write_spr_e( SPR_GPR_BASE + i, INITIAL_GPR_VALUE ); } std::string msg( "The basic CPU core was reset.\n" ); if ( rsp.spr_upr & SPR_UPR_PICP ) { dbg_cpu0_write_spr_e( SPR_PICMR, 0 ); msg += "The CPU PIC unit (Programmable Interrupt Controller) was reset.\n"; } if ( rsp.spr_upr & SPR_UPR_TTP ) { dbg_cpu0_write_spr_e( SPR_TTMR, 0 ); dbg_cpu0_write_spr_e( SPR_TTCR, 0 ); msg += "The CPU Tick Timer unit was reset.\n"; } send_pass_through_command_text_reply( rsp.client_fd, msg.c_str() ); } else throw std::runtime_error( "Unknown target-specific command." ); } catch ( const std::exception & e ) { std::string err_msg( e.what() ); err_msg += "\n"; send_pass_through_command_text_reply( rsp.client_fd, err_msg.c_str() ); } }
static int main_2 ( int argc, char * argv[] ) { try { // This application does not output large number of text messages, // and, if logging is turned off, the user should see the log messages straight away. // Therefore, turn off buffering on stdout and stderr. Afterwards, there is no need // to call fflush( stdout/stderr ) any more. if ( 0 != setvbuf( stdout, NULL, _IONBF, 0 ) ) throw std::runtime_error( format_errno_msg( errno, "Cannot turn off buffering on stdout: " ) ); if ( 0 != setvbuf( stderr, NULL, _IONBF, 0 ) ) throw std::runtime_error( format_errno_msg( errno, "Cannot turn off buffering on stderr: " ) ); bsdl_init(); cable_setup(); if ( parse_args( argc, argv ) ) { config_set_trace( trace_jtag_bit_data ); char * server_port_first_err_char; const long int gdb_rsp_server_port = strtol( port, &server_port_first_err_char, 10 ); if ( *server_port_first_err_char ) { throw std::runtime_error( format_msg( "Failed to parse GDB RSP server port from the given parameter \"%s\".", port ) ); // This alternative code issues a warning and takes a default port number: // printf( "Failed to parse GDB RSP server port \'%s\', using default \'%s\'.\n", port, default_port ); // gdb_rsp_server_port = strtol( default_port, &server_port_first_err_char, 10 ); // if ( *server_port_first_err_char ) // throw std::runtime_error( "Error retrieving the TCP port for the GDB RSP server." ); } cable_init(); // Initialize a new connection to the or1k board, and make sure we are really connected. configure_chain(); #ifdef ENABLE_JSP long int jspserverport; jspserverport = strtol(jspport,&s,10); if(*s) { printf("Failed to get JSP server port \'%s\', using default \'%s\'.\n", jspport, default_jspport); serverPort = strtol(default_jspport,&s,10); if(*s) { printf("Failed to get default JSP port, exiting.\n"); return -1; } } jsp_init(jspserverport); jsp_server_start(); #endif printf("The GDB to JTAG bridge is up and running.\n"); // If you update the signal list, please update the help text too. install_signal_handler( SIGINT , exit_signal_handler ); install_signal_handler( SIGHUP , exit_signal_handler ); install_signal_handler( SIGPIPE, ignore_signal_handler ); // Otherwise, writing to a socket may kill us with a SIGPIPE signal. handle_rsp( gdb_rsp_server_port, listen_on_all_addrs ? false : true, trace_rsp ? true : false, trace_jtag_bit_data ? true : false, &s_exit_request ); if ( s_exit_request ) { printf( "Quitting after receiving signal number %d.\n", s_received_signal_number ); } cable_close(); } bsdl_terminate(); return 0; } catch ( ... ) { bsdl_terminate(); throw; } }
static bool parse_args ( const int argc, char ** const argv ) { port = NULL; force_alt_vjtag = 0; cmd_line_cmd_debug = -1; std::string optstring = "+g:w:x:a:l:c:v:r:b:th"; #ifdef ENABLE_JSP jspport = NULL; optstring += "j:"; #endif const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, { "listen-on-all-addrs", no_argument, &listen_on_all_addrs, 1 }, { "trace-rsp", no_argument, &trace_rsp, 1 }, { "trace-jtag-bit-data", no_argument, &trace_jtag_bit_data, 1 }, { NULL, 0, NULL, 0 } // All zeros, marks the end of the long options list. }; for ( ; ; ) { const int c = getopt_long( argc, argv, optstring.c_str(), longopts, NULL ); if ( c == -1 ) break; // Finished parsing all command-line options. switch ( c ) { case 0: // A long option was processed, nothing else to do here. break; case 'h': print_usage(argv[0]); return false; case 'g': port = optarg; break; #ifdef ENABLE_JSP case 'j': jspport = optarg; break; #endif case 'x': target_dev_pos = atoi(optarg); break; case 'l': { int idx; int val; get_ir_opts(optarg, &idx, &val); // parse the option irset new_elem; new_elem.dev_index = idx; new_elem.ir_length = val; cmd_line_ir_sizes.push_back( new_elem ); break; } case 'c': cmd_line_cmd_debug = strtoul(optarg, NULL, 16); break; case 'v': config_set_vjtag_cmd_vir(strtoul(optarg, NULL, 16)); break; case 'r': config_set_vjtag_cmd_vdr(strtoul(optarg, NULL, 16)); break; case 'a': if(atoi(optarg) == 1) force_alt_vjtag = 1; else force_alt_vjtag = -1; break; case 'b': bsdl_add_directory(optarg); break; default: throw std::runtime_error( "Invalid command-line arguments, use the --help switch for help.\n" ); // print_usage( argv[0] ); // exit(1); } } if(port == NULL) port = default_port; #ifdef ENABLE_JSP if(jspport == NULL) jspport = default_jspport; #endif bool found_cable = false; char * start_str = argv[optind]; int start_idx = optind; for ( int i = optind; i < argc; i++ ) { if ( cable_select( argv[i] ) ) { found_cable = true; cable_name = argv[i]; argv[optind] = argv[start_idx]; // swap the cable name with the other arg, argv[start_idx] = start_str; // keep all cable opts at the end break; } } if( !found_cable ) { throw std::runtime_error( "No valid cable specified." ); } optind = start_idx + 1; // Reset the parse index. // Parse the remaining options for the cable. // Note that this will include unrecognized option from before the cable name. const char * const valid_cable_args = cable_get_args(); for ( ; ; ) { const int c = getopt( argc, argv, valid_cable_args ); if ( c == -1 ) break; // Finished parsing all command-line options. // printf("Got cable opt %c (0x%X)\n", (char)c, c); if ( c == '?' ) { throw std::runtime_error( format_msg( "Unknown cable option '-%c'.", optopt ) ); } cable_parse_opt( c, optarg ); } return true; }
// Resets JTAG, and sets up DEBUG scan chain static void configure_chain ( void ) { printf( "Resetting the JTAG interface...\n" ); tap_reset(); printf( "Enumerating the JTAG chain...\n" ); jtag_enumerate_chain( &discovered_id_codes ); printf("\nDevices discovered on the JTAG chain:\n"); printf("Index\tName\t\tID Code\t\tIR Length\n"); printf("----------------------------------------------------------------\n"); for( unsigned i = 0; i < discovered_id_codes.size(); i++ ) { const char * name; int irlen; if ( discovered_id_codes[i] != IDCODE_INVALID ) { name = bsdl_get_name ( discovered_id_codes[i] ); irlen = bsdl_get_IR_size( discovered_id_codes[i] ); if ( name == NULL ) name = name_not_found; } else { name = name_not_found; irlen = -1; } printf("%d: \t%s \t0x%08X \t%d\n", i, name, discovered_id_codes[i], irlen); } printf("\n"); if ( discovered_id_codes.size() > 1 ) { throw std::runtime_error( "TODO: Support for JTAG chains with more than one device must be tested again." ); } if ( target_dev_pos >= int( discovered_id_codes.size() ) ) { printf("ERROR: Requested target device (%i) beyond highest device index (%u).\n", target_dev_pos, unsigned( discovered_id_codes.size() - 1 )) ; exit(1); } const unsigned int manuf_id = (discovered_id_codes[target_dev_pos] >> 1) & IDCODE_MANUFACTURER_ID_MASK; // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length const int ir_size = get_IR_size(target_dev_pos); printf( "The target device is at JTAG chain position %d and has an IDCODE of 0x%08X.\nThe IR register has a length of %d bits.\n", target_dev_pos, discovered_id_codes[target_dev_pos], ir_size ); config_set_IR_size( ir_size ); // Set the IR prefix / postfix bits int total = 0; for ( int i = 0; i < int( discovered_id_codes.size() ); i++ ) { if(i == target_dev_pos) { config_set_IR_postfix_bits(total); //debug("Postfix bits: %d\n", total); total = 0; continue; } total += get_IR_size(i); debug("Adding %i to total for devidx %i\n", get_IR_size(i), i); } config_set_IR_prefix_bits(total); debug("Prefix bits: %d\n", total); // Note that there's a little translation here, since device index 0 is actually closest to the cable data input config_set_DR_prefix_bits(int(discovered_id_codes.size()) - target_dev_pos - 1); // number of devices between cable data out and target device config_set_DR_postfix_bits(target_dev_pos); // number of devices between target device and cable data in // Set the DEBUG command for the IR of the target device. // If this is a Xilinx device, use USER1 instead of DEBUG // If we Altera Virtual JTAG mode, we don't care. if((force_alt_vjtag == -1) || ((force_alt_vjtag == 0) && (manuf_id != ALTERA_MANUFACTURER_ID))) { const uint32_t cmd = get_debug_cmd(target_dev_pos); if(cmd == TAP_CMD_INVALID) { printf("Unable to find DEBUG command, aborting.\n"); exit(1); } config_set_debug_cmd(cmd); // This may have to be USER1 if this is a Xilinx device } // Enable the kludge for Xilinx BSCAN, if necessary. // Safe, but slower, for non-BSCAN TAPs. if ( manuf_id == XILINX_MANUFACTURER_ID ) { config_set_xilinx_bscan_internal_jtag( true ); } // Set Altera Virtual JTAG mode on or off. If not forced, then enable // if the target device has an Altera manufacturer IDCODE if(force_alt_vjtag == 1) { config_set_alt_vjtag(1); } else if(force_alt_vjtag == -1) { config_set_alt_vjtag(0); } else { if(manuf_id == ALTERA_MANUFACTURER_ID) { config_set_alt_vjtag(1); } else { config_set_alt_vjtag(0); } } printf( "Performing a TAP sanity check (explicitly write the IDCODE instruction code and read back the IDCODE value)...\n" ); const uint32_t cmd = bsdl_get_idcode_cmd( discovered_id_codes[target_dev_pos] ); if ( cmd == TAP_CMD_INVALID ) throw std::runtime_error( "Error: The BSDL file does not contain the IDCODE instruction opcode, which is needed for a basic sanity check." ); uint32_t id_read; jtag_get_idcode( cmd, &id_read ); if ( id_read != discovered_id_codes[target_dev_pos] ) { throw std::runtime_error( format_msg( "The IDCODE sanity test has failed, the IDCODE value read was 0x%08X, but the expected code was 0x%08X.\n", id_read, discovered_id_codes[target_dev_pos] ) ); } printf("IDCODE sanity test passed, the JTAG chain looks OK.\n"); printf("Switching to the debug module of the OR10 TAP...\n"); set_ir_to_cpu_debug_module(); }
/** Helper: sends a message to the appropriate logfiles, at loglevel * <b>severity</b>. If provided, <b>funcname</b> is prepended to the * message. The actual message is derived as from tor_snprintf(format,ap). */ static void logv(int severity, log_domain_mask_t domain, const char *funcname, const char *format, va_list ap) { char buf[10024]; size_t msg_len = 0; int formatted = 0; logfile_t *lf; char *end_of_prefix=NULL; /* Call assert, not tor_assert, since tor_assert calls log on failure. */ assert(format); /* check that severity is sane. Overrunning the masks array leads to * interesting and hard to diagnose effects */ assert(severity >= LOG_ERR && severity <= LOG_DEBUG); LOCK_LOGS(); lf = logfiles; while (lf) { if (! (lf->severities->masks[SEVERITY_MASK_IDX(severity)] & domain)) { lf = lf->next; continue; } if (! (lf->fd >= 0 || lf->is_syslog || lf->callback)) { lf = lf->next; continue; } if (lf->callback && (domain & LD_NOCB)) { lf = lf->next; continue; } if (lf->seems_dead) { lf = lf->next; continue; } if (!formatted) { end_of_prefix = format_msg(buf, sizeof(buf), domain, severity, funcname, format, ap, &msg_len); formatted = 1; } if (lf->is_syslog) { #ifdef HAVE_SYSLOG_H char *m = end_of_prefix; #ifdef MAXLINE /* Some syslog implementations have limits on the length of what you can * pass them, and some very old ones do not detect overflow so well. * Regrettably, they call their maximum line length MAXLINE. */ #if MAXLINE < 64 #warn "MAXLINE is a very low number; it might not be from syslog.h after all" #endif if (msg_len >= MAXLINE) m = tor_strndup(end_of_prefix, MAXLINE-1); #endif syslog(severity, "%s", m); #ifdef MAXLINE if (m != end_of_prefix) { tor_free(m); } #endif #endif lf = lf->next; continue; } else if (lf->callback) { lf->callback(severity, domain, end_of_prefix); lf = lf->next; continue; } if (write_all(lf->fd, buf, msg_len, 0) < 0) { /* error */ /* don't log the error! mark this log entry to be blown away, and * continue. */ lf->seems_dead = 1; } lf = lf->next; } UNLOCK_LOGS(); }
/* **** **** **** **** **** **** **** **** **** **** **** **** * templates_help_dialog: put up an information window without grabbing control * **** **** **** **** **** **** **** **** **** **** **** **** */ static void templates_help_cb( Widget w, XtPointer cbd, XtPointer cbs) { Widget dismiss_btn_area, dismiss_btn; static Widget shell, help_pane; Widget form, help_item, introduction, template_icon, template_text; Dimension h; int i, fbase, x, y; if(shell) { XtPopup(shell, XtGrabNone); return; } /* else */ shell = XtVaCreatePopupShell("xpp-Help", xmDialogShellWidgetClass, root, XmNdeleteResponse, XmUNMAP, NULL); #ifdef EDITRES add_edit_res_handler(shell); #endif common_dialog_setup(shell, popdown_cb, shell); help_pane = XtVaCreateWidget("help-pane", XMPANEDCLASS, shell, /* Motif won't let us set these to 0! */ /* Make small so user can't try to resize */ XmNsashWidth, (Dimension) 1, XmNsashHeight, (Dimension) 1, NULL); introduction = XtVaCreateManagedWidget("introduction", xmLabelGadgetClass, help_pane, XmNlabelString, format_msg(Help_Templates_Tool, HELP_LINE_LEN), XmNalignment, XmALIGNMENT_CENTER, NULL); XtManageChild(introduction); XtVaGetValues(introduction, XmNheight, &h, NULL); XtVaSetValues(introduction, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL); fbase = (template_table_size + 1) & ~0x01; form = XtVaCreateWidget("help-form", xmFormWidgetClass, help_pane, XmNfractionBase, fbase, NULL); for (i=0; i < template_table_size; i++) { x = (fbase / 2) * (i % 2); y = 2 * (i / 2); help_item = XtVaCreateWidget("help-item", xmRowColumnWidgetClass, form, XmNorientation, XmHORIZONTAL, XmNpacking, XmPACK_TIGHT, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, x, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, x + (fbase / 2), XmNtopAttachment, XmATTACH_POSITION, XmNtopPosition, y, XmNbottomAttachment, XmATTACH_POSITION, XmNbottomPosition, y + 2, NULL); template_icon = XtVaCreateManagedWidget("template-icon", xmLabelWidgetClass, help_item, XmNlabelPixmap, get_pixmap(w, template_table[i].bitmap_file, i < template_table_size - 1), XmNlabelType, XmPIXMAP, NULL); template_text = XtVaCreateManagedWidget("template-text", xmLabelGadgetClass, help_item, XmNlabelString, format_msg (template_table[i].help_text, MSG_LINE_LEN), NULL); XtManageChild(help_item); } XtVaSetValues(help_item, XmNbottomAttachment, XmATTACH_FORM, NULL); XtManageChild(form); dismiss_btn_area = XtVaCreateWidget("dismiss_btn_area", xmFormWidgetClass, help_pane, XmNfractionBase, 30, NULL); dismiss_btn = XtVaCreateManagedWidget("Dismiss", xmPushButtonGadgetClass, dismiss_btn_area, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 10, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 20, XmNshowAsDefault, True, XmNdefaultButtonShadowThickness, 1, NULL); XtAddCallback(dismiss_btn, XmNactivateCallback, popdown_cb, shell); XtManageChild(dismiss_btn_area); XtVaGetValues(dismiss_btn, XmNheight, &h, NULL); XtVaSetValues(dismiss_btn_area, XmNpaneMaximum, h, XmNpaneMinimum, h, NULL); XtManageChild(help_pane); XtPopup(shell, XtGrabNone); fix_pane_height(introduction, introduction); fix_pane_height(form, form); fix_pane_height(dismiss_btn_area, dismiss_btn_area); }