void f_aap_log_as_array(INT32 args) { struct log_entry *le; struct log *l = LTHIS->log; int n = 0; pop_n_elems(args); mt_lock( &l->log_lock ); le = l->log_head; l->log_head = l->log_tail = 0; mt_unlock( &l->log_lock ); while(le) { struct log_entry *l; n++; push_log_entry(le); l = le->next; free_log_entry(le); le = l; } { f_aggregate(n); } }
int parse_log( FILE *fp, /* I */ char *job, /* I */ int ind) /* I */ { struct log_entry tmp; /* temporary log entry */ char buf[32768]; /* buffer to read in from file */ char *pa, *pe; /* pointers to use for splitting */ int field_count; /* which field in log entry */ int j = 0; struct tm tms; /* used to convert date to unix date */ static char none[1] = { '\0' }; int lineno = 0; int logcount = 0; tms.tm_isdst = -1; /* mktime() will attempt to figure it out */ while (fgets(buf, sizeof(buf), fp) != NULL) { lineno++; j++; buf[strlen(buf) - 1] = '\0'; field_count = 0; pa = buf; memset(&tmp, 0, sizeof(struct log_entry)); for(field_count = 0; (pa != NULL) && (field_count <= FLD_MSG); field_count++) { /* instead of using strtok every time, conditionally advance the pa (the field pointer) * on semicolons. This prevents data from getting cut out of messages with semicolons in * them */ if(field_count < FLD_MSG) { if((pe = strchr(pa, ';'))) *pe = '\0'; } else { pe = NULL; } switch (field_count) { case FLD_DATE: tmp.date = pa; if(ind == IND_ACCT) field_count += 2; break; case FLD_EVENT: tmp.event = pa; break; case FLD_OBJ: tmp.obj = pa; break; case FLD_TYPE: tmp.type = pa; break; case FLD_NAME: tmp.name = pa; break; case FLD_MSG: tmp.msg = pa; break; } if(pe) pa = pe + 1; else pa = NULL; } /* END for (field_count) */ if ((tmp.name != NULL) && !strncmp(job, tmp.name, strlen(job)) && !isdigit(tmp.name[strlen(job)])) { if (ll_cur_amm >= ll_max_amm) alloc_more_space(); free_log_entry(&log_lines[ll_cur_amm]); if (tmp.date != NULL) { log_lines[ll_cur_amm].date = strdup(tmp.date); if (sscanf(tmp.date, "%d/%d/%d %d:%d:%d", &tms.tm_mon, &tms.tm_mday, &tms.tm_year, &tms.tm_hour, &tms.tm_min, &tms.tm_sec) != 6) log_lines[ll_cur_amm].date_time = -1; /* error in date field */ else { if (tms.tm_year > 1900) tms.tm_year -= 1900; log_lines[ll_cur_amm].date_time = mktime(&tms); } } if (tmp.event != NULL) log_lines[ll_cur_amm].event = strdup(tmp.event); else log_lines[ll_cur_amm].event = none; if (tmp.obj != NULL) log_lines[ll_cur_amm].obj = strdup(tmp.obj); else log_lines[ll_cur_amm].obj = none; if (tmp.type != NULL) log_lines[ll_cur_amm].type = strdup(tmp.type); else log_lines[ll_cur_amm].type = none; if (tmp.name != NULL) log_lines[ll_cur_amm].name = strdup(tmp.name); else log_lines[ll_cur_amm].name = none; if (tmp.msg != NULL) log_lines[ll_cur_amm].msg = strdup(tmp.msg); else log_lines[ll_cur_amm].msg = none; switch (ind) { case IND_SERVER: log_lines[ll_cur_amm].log_file = 'S'; break; case IND_SCHED: log_lines[ll_cur_amm].log_file = 'L'; break; case IND_ACCT: log_lines[ll_cur_amm].log_file = 'A'; break; case IND_MOM: log_lines[ll_cur_amm].log_file = 'M'; break; default: log_lines[ll_cur_amm].log_file = 'U'; /* undefined */ } log_lines[ll_cur_amm].lineno = lineno; ll_cur_amm++; logcount++; } } /* END while (fgets(buf,sizeof(buf),fp) != NULL) */ if (logcount == 0) { /* FAILURE */ return(-1); } /* SUCCESS */ return(0); } /* END parse_log() */
void f_aap_log_as_commonlog_to_file(INT32 args) { struct log_entry *le; struct log *l = LTHIS->log; int n = 0; int mfd, ot=0; struct object *f; struct tm tm; FILE *foo; static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Oct", "Sep", "Nov", "Dec", }; get_all_args("log_as_commonlog_to_file", args, "%o", &f); f->refs++; pop_n_elems(args); apply(f, "query_fd", 0); mfd = fd_dup(sp[-1].u.integer); if(mfd < 1)Pike_error("Bad fileobject to ->log_as_commonlog_to_file\n"); pop_stack(); foo = fdopen( mfd, "w" ); if(!foo) Pike_error("Bad fileobject to ->log_as_commonlog_to_file\n"); THREADS_ALLOW(); mt_lock( &l->log_lock ); le = l->log_head; l->log_head = l->log_tail = 0; mt_unlock( &l->log_lock ); while(le) { int i; struct tm *tm_p; struct log_entry *l = le->next; /* remotehost rfc931 authuser [date] "request" status bytes */ if(le->t != ot) { time_t t = (time_t)le->t; #ifdef HAVE_GMTIME_R gmtime_r( &t, &tm ); #else #ifdef HAVE_GMTIME tm_p = gmtime( &t ); /* This will break if two threads run gmtime() at once. */ #else #ifdef HAVE_LOCALTIME tm_p = localtime( &t ); /* This will break if two threads run localtime() at once. */ #endif #endif if (tm_p) tm = *tm_p; #endif ot = le->t; } /* date format: [03/Feb/1998:23:08:20 +0000] */ /* GET [URL] HTTP/1.0 */ for(i=13; i<le->raw.len; i++) if(le->raw.str[i] == '\r') { le->raw.str[i] = 0; break; } #ifdef HAVE_INET_NTOP if(SOCKADDR_FAMILY(le->from) != AF_INET) { char buffer[64]; fprintf(foo, "%s - %s [%02d/%s/%d:%02d:%02d:%02d +0000] \"%s\" %d %ld\n", inet_ntop(SOCKADDR_FAMILY(le->from), SOCKADDR_IN_ADDR(le->from), buffer, sizeof(buffer)), /* hostname */ "-", /* remote-user */ tm.tm_mday, month[tm.tm_mon], tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec, /* date */ le->raw.str, /* request line */ le->reply, /* reply code */ DO_NOT_WARN((long)le->sent_bytes)); /* bytes transfered */ } else #endif /* HAVE_INET_NTOP */ fprintf(foo, "%d.%d.%d.%d - %s [%02d/%s/%d:%02d:%02d:%02d +0000] \"%s\" %d %ld\n", ((unsigned char *)&le->from.ipv4.sin_addr)[ 0 ], ((unsigned char *)&le->from.ipv4.sin_addr)[ 1 ], ((unsigned char *)&le->from.ipv4.sin_addr)[ 2 ], ((unsigned char *)&le->from.ipv4.sin_addr)[ 3 ], /* hostname */ "-", /* remote-user */ tm.tm_mday, month[tm.tm_mon], tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec, /* date */ le->raw.str, /* request line */ le->reply, /* reply code */ DO_NOT_WARN((long)le->sent_bytes)); /* bytes transfered */ free_log_entry( le ); n++; le = l; } fclose(foo); fd_close(mfd); THREADS_DISALLOW(); push_int(n); }