X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Freqstat.c;h=34b7ce37df1c49e189e9a407b46af9680137b5cf;hb=5dce4f6c7d1f5fb0a4d4bcf72c11ee0c91ebcfdf;hp=8a22dd8b8def14e6ad5dc78059a3b400cdc59353;hpb=38b22d1a1b70b48faf254383f4f28c31e39a0c72;p=doldaconnect.git diff --git a/daemon/reqstat.c b/daemon/reqstat.c index 8a22dd8..34b7ce3 100644 --- a/daemon/reqstat.c +++ b/daemon/reqstat.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -40,7 +41,7 @@ void filelog(char *format, ...) { FILE *out; va_list args; - char *b; + char *b, *t, *p; time_t now; if(fn == NULL) @@ -53,24 +54,60 @@ void filelog(char *format, ...) va_start(args, format); b = vsprintf2(format, args); va_end(args); - fprintf(out, "%s: %s\n", ctime(&now), b); + t = ctime(&now); + if((p = strchr(t, '\n')) != NULL) + *p = 0; + fprintf(out, "%s: %s\n", t, b); free(b); fclose(out); } +void xainc(wchar_t *file, char *an, off_t inc) +{ + char buf[32]; + ssize_t al; + off_t val; + char *fn; + + if((fn = icswcstombs(file, NULL, NULL)) == NULL) { + flog(LOG_WARNING, "could not convert filename %ls into local charset: %s", file, strerror(errno)); + return; + } + if((al = getxattr(fn, an, buf, sizeof(buf) - 1)) < 0) { + if(errno != ENOATTR) { + flog(LOG_WARNING, "could not get xattr %s on %s: %s", an, fn, strerror(errno)); + return; + } + val = 0; + } else { + buf[al] = 0; + val = strtoll(buf, NULL, 10); + } + val += inc; + al = snprintf(buf, sizeof(buf), "%ji", (intmax_t)val); + if(setxattr(fn, an, buf, al, 0) < 0) + flog(LOG_WARNING, "could not set xattr %s on %s: %s", an, fn, strerror(errno)); +} + void request(struct transfer *transfer, struct trdata *data) { filelog("request %ls", transfer->path); + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-req", 1); } void start(struct transfer *transfer, struct trdata *data) { - filelog("start %ls at %zi\n", transfer->path, data->startpos); + filelog("start %ls at %zi", transfer->path, data->startpos); + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-started", 1); } void finish(struct transfer *transfer, struct trdata *data) { - filelog("finish %ls at %zi, total %zi\n", transfer->path, transfer->curpos, transfer->curpos - data->startpos); + filelog("finish %ls at %zi, total %zi", transfer->path, transfer->curpos, transfer->curpos - data->startpos); + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-bytes", transfer->curpos - data->startpos); } static int chattr(struct transfer *transfer, wchar_t *attrib, struct trdata *data) @@ -92,7 +129,8 @@ static int chattr(struct transfer *transfer, wchar_t *attrib, struct trdata *dat static int destroy(struct transfer *transfer, struct trdata *data) { - finish(transfer, data); + if(transfer->curpos > data->startpos) + finish(transfer, data); free(data); return(0); } @@ -113,7 +151,7 @@ static int chfile(struct configvar *var, void *uudata) { if(fn != NULL) free(fn); - if(var->val.str[0] == L'0') { + if(var->val.str[0] == L'\0') { fn = NULL; } else { if((fn = icwcstombs(var->val.str, NULL)) == NULL) @@ -126,6 +164,7 @@ static int init(int hup) { if(!hup) { GCBREG(newtransfercb, reg, NULL); + chfile(confgetvar("reqstat", "file"), NULL); CBREG(confgetvar("reqstat", "file"), conf_update, chfile, NULL, NULL); } return(0); @@ -135,6 +174,12 @@ static struct configvar myvars[] = { /** The name of a file to log upload request information to. If * unspecified, upload requests will not be logged. */ {CONF_VAR_STRING, "file", {.str = L""}}, + /** If set to true, upload statistics of files will be accumulated + * in counters stored in extends attributes (see attr(5)) on the + * files themselves. The data accumulated is the number of + * requests, the number of successfully started uploads and the + * number of uploaded bytes. */ + {CONF_VAR_BOOL, "xa", {.num = 0}}, {CONF_VAR_END} };