X-Git-Url: http://git.dolda2000.com/gitweb/?a=blobdiff_plain;f=daemon%2Freqstat.c;h=18349529fa35681bf6c245a8f2ebeac62a7f4cdf;hb=4e564b59c7c565387c4907017dfacce2ef761f8a;hp=41ca1c6d46ebcdc6df3f1141de9aabd3ec37a82f;hpb=f4b020f44cca3524e521c7981d8d4eb02582c9f1;p=doldaconnect.git diff --git a/daemon/reqstat.c b/daemon/reqstat.c index 41ca1c6..1834952 100644 --- a/daemon/reqstat.c +++ b/daemon/reqstat.c @@ -30,6 +30,10 @@ #include "module.h" #include "log.h" +#ifdef HAVE_XATTR +#include +#endif + struct trdata { size_t startpos; }; @@ -40,7 +44,7 @@ void filelog(char *format, ...) { FILE *out; va_list args; - char *b; + char *b, *t, *p; time_t now; if(fn == NULL) @@ -53,24 +57,70 @@ 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); } +#ifdef HAVE_XATTR +void xainc(wchar_t *file, char *an, off_t inc) +{ + char buf[32]; + ssize_t al; + off_t val; + char *fn; + + if(file[0] != L'/') + return; + 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)); +} +#endif + void request(struct transfer *transfer, struct trdata *data) { filelog("request %ls", transfer->path); +#ifdef HAVE_XATTR + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-req", 1); +#endif } 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); +#ifdef HAVE_XATTR + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-started", 1); +#endif } 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); +#ifdef HAVE_XATTR + if(confgetint("reqstat", "xa")) + xainc(transfer->path, "user.dc-bytes", transfer->curpos - data->startpos); +#endif } static int chattr(struct transfer *transfer, wchar_t *attrib, struct trdata *data) @@ -92,7 +142,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 +164,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) @@ -122,18 +173,26 @@ static int chfile(struct configvar *var, void *uudata) return(0); } -static void preinit(int hup) +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); } 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} }; @@ -141,8 +200,8 @@ static struct module me = { .conf = { .vars = myvars }, - .preinit = preinit, + .init = init, .name = "reqstat" }; -MODULE(me); +MODULE(me)