/* $Header: /CVSROOT/debris/drisnext.h,v 1.7 2005/08/15 01:04:52 tino Exp $ * * DebRIS: DEBian Remote Install Scripter * Fetch the "next" step from the network (or whatever). * * $Log: drisnext.h,v $ * Revision 1.7 2005/08/15 01:04:52 tino * all functions now have a prefix (dris_) * * Revision 1.6 2005/08/15 00:47:45 tino * updates for DebRIS improvements * * Revision 1.5 2005/08/13 22:59:12 tino * additional functions, see ChangeLog * * Revision 1.4 2005/07/25 03:24:23 tino * md5 functions moved to drismd5 * * Revision 1.3 2005/07/24 22:16:54 tino * now use snprintf * * Revision 1.2 2005/06/01 02:39:04 tino * now it compiles * * Revision 1.1 2005/06/01 02:12:35 tino * first version. As SirbeD is missing, this just does nothing yet. */ #include "driscurl.h" #include #include "tino/xd.h" static const char * dris_next_check(struct dris_buf *buf) { int i; const char *cmp; if (config.debug) tino_xd(stderr, "<", 8, 0, buf->buf, buf->len); for (i=0; buf->buf[i]!='\r' || buf->buf[i+1]!='\n'; i++) if (!buf->buf[i]) return "missing first line terminator"; if ((i+=2)>buf->len) return "BUG: i>buf->len"; dris_md5_cksum_init(); dris_md5_add(buf->buf+i, buf->len-i); cmp = dris_md5_get(); if (strncmp(buf->buf, cmp, strlen(cmp))) return "checksum mismatch"; dris_buf_add(dris_buf_reset(config.out), buf->buf+i, buf->len-i); return 0; } /* This here is the black magic function to fetch the next step to do. * * It knows about the config struct. * It contacts URL for data transfer. * It sends config.result and config.out to the network. * It reads config.in from the network. * It verifies the correctness of the received data. */ static int dris_next(void) { static struct dris_buf *in, *out; static int ( *fn)(struct dris_buf *, struct dris_buf *) = dris_curl; int retry; char tmp[256]; if (!in) in = dris_buf_new(); if (!out) out = dris_buf_new(); snprintf(tmp, sizeof tmp, "%s %lld\r\n%d\r\n", config.id, config.cnt, config.result); dris_md5_cksum_init(); dris_md5_add_s(tmp); dris_md5_add(config.out->buf, config.out->len); dris_buf_reset(in); dris_buf_add_s(in, dris_md5_get()); dris_buf_add_s(in, tmp); dris_buf_add(in, config.out->buf, config.out->len); retry = 0; for (;;) { int err; dris_buf_reset(out); dris_verbose("[%lld] send %ld bytes to %s\n", config.cnt, (long)in->len, config.url); if ((err=fn(in, out))==0) { const char *err; dris_verbose("* got %lu bytes\n", (unsigned long)out->len); err = dris_next_check(out); if (!err) return 1; dris_verbose("* data error: %s\n", err); } retry++; dris_info("* failed with error code %d", err); err = (retry>60 ? 60 : retry); dris_verbose(", sleeping %d ..", err); sleep(err); dris_info(" retry %d\n", retry); } }