//! //! Log-printing function without a specific log level. It is essentially printf() that will go verbatim, //! with just timestamp as prefix and at any log level, into the current log or stdout, if no log was open. //! //! @param[in] format the format of the log message //! @param[in] ... the variable argument part filling the format //! //! @return 0 on success. If negative, error with vsnprintf() or if 1 means error with log_line() //! //! @todo Chuck to evaluate if we cannot standardize the error code returned. //! //! @see log_line() //! int logprintf(const char *format, ...) { char buf[LOGLINEBUF]; // start with current timestamp int offset = fill_timestamp(buf, sizeof(buf)); // append the log message passed via va_list va_list ap; va_start(ap, format); int rc = vsnprintf(buf + offset, sizeof(buf) - offset - 1, format, ap); va_end(ap); if (rc < 0) return rc; return log_line(buf); }
//! //! Log-printing function without a specific log level. It is essentially printf() that will go verbatim, //! with just timestamp as prefix and at any log level, into the current log or stdout, if no log was open. //! //! @param[in] format the format of the log message //! @param[in] ... the variable argument part filling the format //! //! @return 0 on success. If negative, error with vsnprintf() or if 1 means error with log_line() //! //! @see log_line() //! //! @todo Evaluate if we cannot standardize the error code returned. //! int logprintf(const char *format, ...) { int rc = -1; int offset = -1; char buf[LOGLINEBUF] = ""; va_list ap = { {0} }; // start with current timestamp offset = fill_timestamp(buf, sizeof(buf)); // append the log message passed via va_list va_start(ap, format); { rc = vsnprintf(buf + offset, sizeof(buf) - offset - 1, format, ap); } va_end(ap); if (rc < 0) return (rc); return (log_line(buf)); }
static void send_faked_ack(tc_user_t *u) { tc_ip_header_t *ip_header; tc_tcp_header_t *tcp_header; unsigned char *p, frame[FAKE_FRAME_LEN]; memset(frame, 0, FAKE_FRAME_LEN); p = frame + ETHERNET_HDR_LEN; ip_header = (tc_ip_header_t *) p; tcp_header = (tc_tcp_header_t *) (p + IP_HEADER_LEN); ip_header->version = 4; ip_header->ihl = IP_HEADER_LEN/4; ip_header->frag_off = htons(IP_DF); ip_header->ttl = 64; ip_header->protocol = IPPROTO_TCP; ip_header->saddr = u->src_addr; ip_header->daddr = u->dst_addr; tcp_header->source = u->src_port; tcp_header->dest = u->dst_port; tcp_header->seq = u->exp_seq; tcp_header->ack_seq = u->exp_ack_seq; tcp_header->window = htons(65535); tcp_header->ack = 1; if (u->state.timestamped) { ip_header->tot_len = htons(FAKE_IP_TS_DATAGRAM_LEN); tcp_header->doff = TCP_HEADER_DOFF_TS_VALUE; fill_timestamp(u, tcp_header); } else { ip_header->tot_len = htons(FAKE_MIN_IP_DATAGRAM_LEN); tcp_header->doff = TCP_HEADER_DOFF_MIN_VALUE; } process_packet(u, frame); }
//! //! Main log-printing function, which will dump a line into a log, with a prefix appropriate for //! the log level, given that the log level is above the threshold. //! //! @param[in] func the caller function name (i.e. __FUNCTION__) //! @param[in] file the file in which the caller function reside (i.e. __FILE__) //! @param[in] line the line at which this function was called (i.e. __LINE__) //! @param[in] level the log level for this message //! @param[in] format the format string of the message //! @param[in] ... the variable argument part of the format //! //! @return 0 on success, -1 on failure with this function or 1 if log_line() failed. //! //! @see log_line() //! //! @pre \li The func field must not be null if the prefix spec contains 'm'. //! \li The file field must not be null if the prefix spec contains 'F'. //! \li The log level must be valid and greather than or equal to the configured log level //! \li The format string must not be null. //! //! @post If the given level if greater or equal to the configured log level, the message will be //! printed into our log file or syslog. //! //! @todo evaluate if we cannot standardize the error code returned. //! int logprintfl(const char *func, const char *file, int line, log_level_e level, const char *format, ...) { int rc = -1; int left = 0; int size = 0; int offset = 0; char *s = NULL; char c = '\0'; char cn = '\0'; boolean custom_spec = FALSE; char buf[LOGLINEBUF] = ""; va_list ap = { {0} }; const char *prefix_spec = NULL; // return if level is invalid or below the threshold if (level < log_level) { return (0); } if ((level < 0) || (level > EUCA_LOG_OFF)) { // unexpected log level return (-1); } if (strcmp(log_custom_prefix, USE_STANDARD_PREFIX) == 0) { prefix_spec = log_level_prefix[log_level]; custom_spec = FALSE; } else { prefix_spec = log_custom_prefix; custom_spec = TRUE; } // go over prefix format for the log level (defined in log.h or custom) for (; *prefix_spec != '\0'; prefix_spec++) { s = buf + offset; if ((left = sizeof(buf) - offset - 1) < 1) { // not enough room in internal buffer for a prefix return -1; } // see if we have a formatting character or a regular one c = prefix_spec[0]; cn = prefix_spec[1]; if ((c != '%') // not a special formatting char || (c == '%' && cn == '%') // formatting char, escaped || (c == '%' && cn == '\0')) { // formatting char at the end s[0] = c; s[1] = '\0'; offset++; if ((c == '%') && (cn == '%')) { // swallow the one extra '%' in input prefix_spec++; } continue; } // move past the '%' to the formatting char prefix_spec++; size = 0; switch (*prefix_spec) { case 'T': // timestamp size = fill_timestamp(s, left); break; case 'L':{ // log-level char l[6]; euca_strncpy(l, log_level_names[level], 6); // we want hard truncation size = snprintf(s, left, "%5s", l); break; } case 'p':{ // process ID char p[11]; snprintf(p, sizeof(p), "%010d", getpid()); // 10 chars is enough for max 32-bit unsigned integer size = print_field_truncated(&prefix_spec, s, left, p); break; } case 't':{ // thread ID char t[21]; snprintf(t, sizeof(t), "%020d", (pid_t) syscall(SYS_gettid)); // 20 chars is enough for max 64-bit unsigned integer size = print_field_truncated(&prefix_spec, s, left, t); break; } case 'm': // method size = print_field_truncated(&prefix_spec, s, left, func); break; case 'F':{ // file-and-line char file_and_line[64]; snprintf(file_and_line, sizeof(file_and_line), "%s:%d", file, line); size = print_field_truncated(&prefix_spec, s, left, file_and_line); break; } case 's':{ // max RSS of the process struct rusage u; bzero(&u, sizeof(struct rusage)); getrusage(RUSAGE_SELF, &u); // unfortunately, many fields in 'struct rusage' aren't supported on Linux (notably: ru_ixrss, ru_idrss, ru_isrss) char size_str[64]; snprintf(size_str, sizeof(size_str), "%05ld", u.ru_maxrss / 1024); size = print_field_truncated(&prefix_spec, s, left, size_str); break; } case '?': // not supported currently s[0] = '?'; s[1] = '\0'; size = 1; break; default: s[0] = *prefix_spec; s[1] = '\0'; size = 1; break; } if (size < 0) { // something went wrong in the snprintf()s above logprintf("error in prefix construction in logprintfl()\n"); return -1; } offset += size; } // add a space between the prefix and the message proper if ((offset > 0) && ((sizeof(buf) - offset - 1) > 0)) { buf[offset++] = ' '; buf[offset] = '\0'; } // append the log message passed via va_list va_start(ap, format); { rc = vsnprintf(buf + offset, sizeof(buf) - offset - 1, format, ap); } va_end(ap); if (rc < 0) return (rc); if (syslog_facility != -1) { // log to syslog, at the appropriate level: euca DEBUG, TRACE, and EXTREME use syslog's DEBUG int l = LOG_DEBUG; if (level == EUCA_LOG_ERROR) l = LOG_ERR; else if (level == EUCA_LOG_WARN) l = LOG_WARNING; else if (level == EUCA_LOG_INFO) l = LOG_INFO; if (custom_spec) syslog(l, buf); else syslog(l, buf + offset); } return (log_line(buf)); }
// Main log-printing function, which will dump a line into // a log, with a prefix appropriate for the log level, given // that the log level is above the threshold. int logprintfl (int level, const char *format, ...) { // return if level is invalid or below the threshold if (level < log_level) { return 0; } else if (level < 0 || level > EUCAOFF) { return -1; // unexpected log level } char buf [LOGLINEBUF]; int offset = 0; // go over prefix format for the log level (defined in log.h) for (char * prefix_spec = (strlen(log_custom_prefix) > 0) ? log_custom_prefix : log_level_prefix [log_level]; * prefix_spec != '\0'; prefix_spec++) { char * s = buf + offset; int left = sizeof (buf) - offset - 1; if (left < 1) { return -1; // not enough room in internal buffer for a prefix } int size = 0; switch (* prefix_spec) { case 'T': // timestamp size = fill_timestamp (s, left); break; case 'L': { // log-level char l [6]; safe_strncpy (l, log_level_names [level], 6); // we want hard truncation size = snprintf (s, left, "%5s", l); break; } case 'p': { // process ID char p [11]; snprintf (p, sizeof (p), "%010d", getpid()); // 10 chars is enough for max 32-bit unsigned integer size = print_field_truncated (&prefix_spec, s, left, p); break; } case 't': { // thread ID char t [21]; snprintf (t, sizeof (t), "%020d", (pid_t) syscall (SYS_gettid)); // 20 chars is enough for max 64-bit unsigned integer size = print_field_truncated (&prefix_spec, s, left, t); break; } case 'm': // method size = print_field_truncated (&prefix_spec, s, left, _log_curr_method); break; case 'F': { // file-and-line char file_and_line [64]; snprintf (file_and_line, sizeof (file_and_line), "%s:%d", _log_curr_file, _log_curr_line); size = print_field_truncated (&prefix_spec, s, left, file_and_line); break; } case '?': s [0] = '?'; // not supported currently s [1] = '\0'; size = 1; break; default: s [0] = * prefix_spec; s [1] = '\0'; size = 1; } if (size < 0) { logprintf ("error in prefix construction in logprintfl()\n"); return -1; // something went wrong in the snprintf()s above } offset += size; } // append the log message passed via va_list va_list ap; va_start(ap, format); int rc = vsnprintf (buf + offset, sizeof (buf) - offset - 1, format, ap); va_end(ap); if (rc<0) return rc; return log_line (buf); }