/*
* Software Updater - server side
*
* Copyright © 2012-2016 Intel Corporation.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2 or later of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authors:
* Arjan van de Ven
* Tim Pepper
*
*/
#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
#include
#include
#include "swupd.h"
static FILE *logfile[2];
static struct timeval start_time;
void init_log(const char *prefix, const char *bundle, int start, int end)
{
char *filename;
string_or_die(&filename, "%s%s-from-%i-to-%i.log", prefix, bundle, start, end);
logfile[0] = fopen(filename, "w");
free(filename);
gettimeofday(&start_time, NULL);
}
void init_log_stdout(void)
{
logfile[1] = stdout;
gettimeofday(&start_time, NULL);
}
/* turn a time delta into a decimal string showing elapsed seconds, or an
* empty string if the time was less than 1ms */
char *get_elapsed_time(struct timeval *t1, struct timeval *t2)
{
char *elapsed = NULL;
double d = 0.0;
// subtract off of "now" the swupd starting time
t2->tv_sec -= start_time.tv_sec;
while (t2->tv_usec < start_time.tv_usec) {
t2->tv_sec--;
t2->tv_usec += 1000000;
}
t2->tv_usec -= start_time.tv_usec;
// if the start was not "0", subtract to get delta
if (t1->tv_usec || t1->tv_sec) {
d = t2->tv_sec * 1000000.0 + t2->tv_usec;
d -= t1->tv_sec * 1000000.0 + t1->tv_usec;
d = d / 1000000.0;
// highlight costly operations by only printing > 1ms deltas
if (d > 0.001) {
string_or_die(&elapsed, "%5.3f", d);
} else {
string_or_die(&elapsed, " ");
}
}
return elapsed;
}
void __log_message(struct file *file, char *msg, char *filename, int linenr, const char *fmt, ...)
{
char *buf = NULL;
struct timeval current_time;
static struct timeval previous_time;
va_list ap;
char *logstring = NULL;
char filebuf[4096];
char filebuf2[4096];
int i;
if (!logfile[0] && !logfile[1]) {
return;
}
gettimeofday(¤t_time, NULL);
logstring = get_elapsed_time(&previous_time, ¤t_time);
previous_time = current_time;
va_start(ap, fmt);
if (vasprintf(&buf, fmt, ap) < 0) {
assert(0);
}
va_end(ap);
filebuf[4095] = 0;
filebuf2[0] = 0;
strncpy(filebuf, filename, 4095);
if (file) {
strncpy(filebuf2, file->filename, 4095);
}
while (strlen(filebuf) < 29) {
strcat(filebuf, " ");
}
while (strlen(filebuf2) < 30) {
strcat(filebuf2, " ");
}
for (i = 0; i < 2; i++) {
if (logfile[i]) {
fprintf(logfile[i], "%3i.%03i %5s %s:%03i\t| %s\t| %s\t| %s\n",
(int)current_time.tv_sec, (int)current_time.tv_usec / 1000, logstring, filebuf, linenr, filebuf2, msg, buf);
fflush(logfile[i]);
}
}
free(logstring);
free(buf);
}
void close_log(int version, int exit_status)
{
struct timeval current_time;
int t_sec;
int t_msec;
if (!logfile[0] && !logfile[1]) {
return;
}
gettimeofday(¤t_time, NULL);
current_time.tv_sec -= start_time.tv_sec;
while (current_time.tv_usec < start_time.tv_usec) {
current_time.tv_sec--;
current_time.tv_usec += 1000000;
}
current_time.tv_usec -= start_time.tv_usec;
t_sec = (int)current_time.tv_sec;
t_msec = (int)current_time.tv_usec / 1000;
LOG(NULL, "Update build duration", "%i.%03i seconds", t_sec, t_msec);
printf("\n\nUpdate build duration was %i.%03i seconds\n", t_sec, t_msec);
if (exit_status == EXIT_SUCCESS) {
LOG(NULL, "Update build success", "version %i", version);
printf("Update complete. System update built for version %i\n", version);
} else {
LOG(NULL, "Update build failure", "version %i", version);
printf("Update build failed for version %i\n", version);
}
if (logfile[0]) {
fclose(logfile[0]);
logfile[0] = NULL;
}
}