From 9f82cb1046fc739cb221d08c1b25d3eb192d2bb9 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 27 Apr 2002 10:58:52 +0000 Subject: [PATCH] Fix Verify MD5 and poll for msgs in gconsole git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/cats/sql_create.c | 2 +- bacula/src/dird/ua_input.c | 23 ++- bacula/src/dird/verify.c | 351 ++++++++++++++++++----------------- bacula/src/filed/backup.c | 13 -- bacula/src/filed/verify.c | 86 +++++---- bacula/src/version.h | 4 +- 6 files changed, 251 insertions(+), 228 deletions(-) diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 7ad6497cef..82b6daebcc 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -502,7 +502,7 @@ static int db_create_file_record(B_DB *mdb, ATTR_DBR *ar) /* Must create it */ Mmsg(&mdb->cmd, "INSERT INTO File (FileIndex, JobId, PathId, FilenameId, \ -LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \" \")", +LStat, MD5) VALUES (%d, %d, %d, %d, \"%s\", \"0\")", (int)ar->FileIndex, ar->JobId, ar->PathId, ar->FilenameId, ar->attr); diff --git a/bacula/src/dird/ua_input.c b/bacula/src/dird/ua_input.c index 53250db4a3..bd88cceb2b 100644 --- a/bacula/src/dird/ua_input.c +++ b/bacula/src/dird/ua_input.c @@ -42,13 +42,24 @@ int get_cmd(UAContext *ua, char *prompt) ua->cmd[0] = 0; bnet_fsend(sock, "%s", prompt); bnet_sig(sock, BNET_PROMPT); /* request more input */ - if (bnet_recv(sock) < 0) { - return 0; + for ( ;; ) { + if (bnet_recv(sock) < 0) { + return 0; + } + ua->cmd = (char *) check_pool_memory_size(ua->cmd, sock->msglen+1); + strcpy(ua->cmd, sock->msg); + ua->cmd[sock->msglen] = 0; + strip_trailing_junk(ua->cmd); + if (strcmp(ua->cmd, ".messages") == 0) { + qmessagescmd(ua, ua->cmd); + } + /* ****FIXME**** if .command, go off and do it. For now ignore it. */ + if (ua->cmd[0] == '.' && ua->cmd[1] != 0) { + continue; /* dot command */ + } + /* Lone dot => break or actual response */ + break; } - ua->cmd = (char *) check_pool_memory_size(ua->cmd, sock->msglen+1); - strcpy(ua->cmd, sock->msg); - ua->cmd[sock->msglen] = 0; - strip_trailing_junk(ua->cmd); return 1; } diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index aa6e1a351f..825758a3f1 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -310,7 +310,10 @@ Termination: %s\n"), term_msg); Dmsg0(100, "Leave verify_cleanup()\n"); - + if (jcr->fname) { + free_memory(jcr->fname); + jcr->fname = NULL; + } } /* @@ -326,6 +329,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, int last_full_id) int stat = JS_Terminated; char buf[MAXSTRING]; char *fname = (char *)get_pool_memory(PM_MESSAGE); + int do_MD5 = FALSE; memset(&fdbr, 0, sizeof(FILE_DBR)); fd = jcr->file_bsock; @@ -336,176 +340,181 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, int last_full_id) * Get Attributes and MD5 Signature from File daemon */ while ((n=bget_msg(fd, 0)) > 0) { - long file_index, attr_file_index; - int stream; - char *attr, *p; - char Opts_MD5[MAXSTRING]; /* Verify Opts or MD5 signature */ - int do_MD5; - - fname = (char *)check_pool_memory_size(fname, fd->msglen); - jcr->fname = (char *)check_pool_memory_size(fname, fd->msglen); - Dmsg1(50, "Atts+MD5=%s\n", fd->msg); - if ((len = sscanf(fd->msg, "%ld %d %100s %s", &file_index, &stream, - Opts_MD5, fname)) != 4) { - Jmsg3(jcr, M_FATAL, 0, _("birdmsglen, fd->msg); - jcr->JobStatus = JS_ErrorTerminated; - return 0; - } - /* - * Got attributes stream, decode it - */ - if (stream == STREAM_UNIX_ATTRIBUTES) { - attr_file_index = file_index; /* remember attribute file_index */ - len = strlen(fd->msg); - attr = &fd->msg[len+1]; - decode_stat(attr, &statf); /* decode file stat packet */ - do_MD5 = FALSE; - jcr->fn_printed = FALSE; - strcpy(jcr->fname, fname); /* move filename into JCR */ - - Dmsg2(11, "dirdfname); - Dmsg1(20, "dirddb, jcr->fname, &fdbr); - - if (fdbr.FileId == 0) { - Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname); - Dmsg1(20, _("File not in catalog: %s\n"), jcr->fname); - stat = JS_Differences; - continue; - } else { - /* - * mark file record as visited by stuffing the - * current JobId, which is unique, into the FileIndex - */ - db_mark_file_record(jcr->db, fdbr.FileId, jcr->JobId); - } - - Dmsg2(20, "Found %s in catalog. Opts=%s\n", jcr->fname, Opts_MD5); - decode_stat(fdbr.LStat, &statc); /* decode catalog stat */ - strip_trailing_junk(jcr->fname); - /* - * Loop over options supplied by user and verify the - * fields he requests. - */ - for (p=Opts_MD5; *p; p++) { - switch (*p) { - case 'i': /* compare INODEs */ - if (statc.st_ino != statf.st_ino) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %x File: %x\n"), - statc.st_ino, statf.st_ino); - stat = JS_Differences; - } - break; - case 'p': /* permissions bits */ - if (statc.st_mode != statf.st_mode) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"), - statc.st_mode, statf.st_mode); - stat = JS_Differences; - } - break; - case 'n': /* number of links */ - if (statc.st_nlink != statf.st_nlink) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"), - statc.st_nlink, statf.st_nlink); - stat = JS_Differences; - } - break; - case 'u': /* user id */ - if (statc.st_uid != statf.st_uid) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %d File: %d\n"), - statc.st_uid, statf.st_uid); - stat = JS_Differences; - } - break; - case 'g': /* group id */ - if (statc.st_gid != statf.st_gid) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %d File: %d\n"), - statc.st_gid, statf.st_gid); - stat = JS_Differences; - } - break; - case 's': /* size */ - if (statc.st_size != statf.st_size) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %d File: %d\n"), - statc.st_size, statf.st_size); - stat = JS_Differences; - } - break; - case 'a': /* access time */ - if (statc.st_atime != statf.st_atime) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n")); - stat = JS_Differences; - } - break; - case 'm': - if (statc.st_mtime != statf.st_mtime) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n")); - stat = JS_Differences; - } - break; - case 'c': /* ctime */ - if (statc.st_ctime != statf.st_ctime) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n")); - stat = JS_Differences; - } - break; - case 'd': /* file size decrease */ - if (statc.st_size > statf.st_size) { - prt_fname(jcr); - Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %d File: %d\n"), - statc.st_size, statf.st_size); - stat = JS_Differences; - } - break; - case '5': /* compare MD5 */ - do_MD5 = TRUE; - break; - case ':': - case 'V': - default: - break; - } - } - /* - * Got MD5 Signature from Storage daemon - * It came across in the Opts_MD5 field. - */ - } else if (stream == STREAM_MD5_SIGNATURE) { - if (attr_file_index != file_index) { - Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"), - file_index, attr_file_index); - jcr->JobStatus = JS_ErrorTerminated; - return 0; - } else if (do_MD5) { - db_escape_string(buf, Opts_MD5, strlen(Opts_MD5)); - if (strcmp(buf, fdbr.MD5) != 0) { - prt_fname(jcr); - if (debug_level >= 10) { - Jmsg(jcr, M_INFO, 0, _(" MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5); - } else { - Jmsg(jcr, M_INFO, 0, _(" MD5 differs.\n")); - } - stat = JS_Differences; - } - } - } - jcr->jr.JobFiles = file_index; - + long file_index, attr_file_index; + int stream; + char *attr, *p; + char Opts_MD5[MAXSTRING]; /* Verify Opts or MD5 signature */ + + fname = (char *)check_pool_memory_size(fname, fd->msglen); + jcr->fname = (char *)check_pool_memory_size(jcr->fname, fd->msglen); + Dmsg1(50, "Atts+MD5=%s\n", fd->msg); + if ((len = sscanf(fd->msg, "%ld %d %100s %s", &file_index, &stream, + Opts_MD5, fname)) != 4) { + Jmsg3(jcr, M_FATAL, 0, _("birdmsglen, fd->msg); + jcr->JobStatus = JS_ErrorTerminated; + return 0; + } + /* + * Got attributes stream, decode it + */ + if (stream == STREAM_UNIX_ATTRIBUTES) { + attr_file_index = file_index; /* remember attribute file_index */ + len = strlen(fd->msg); + attr = &fd->msg[len+1]; + decode_stat(attr, &statf); /* decode file stat packet */ + do_MD5 = FALSE; + jcr->fn_printed = FALSE; + strip_trailing_junk(fname); + strcpy(jcr->fname, fname); /* move filename into JCR */ + + Dmsg2(040, "dirdfname); + Dmsg1(20, "dirddb, jcr->fname, &fdbr)) { + Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname); + Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname); + stat = JS_Differences; + continue; + } else { + /* + * mark file record as visited by stuffing the + * current JobId, which is unique, into the FileIndex + */ + db_mark_file_record(jcr->db, fdbr.FileId, jcr->JobId); + } + + Dmsg3(100, "Found %s in catalog. inx=%d Opts=%s\n", jcr->fname, + file_index, Opts_MD5); + decode_stat(fdbr.LStat, &statc); /* decode catalog stat */ + /* + * Loop over options supplied by user and verify the + * fields he requests. + */ + for (p=Opts_MD5; *p; p++) { + switch (*p) { + case 'i': /* compare INODEs */ + if (statc.st_ino != statf.st_ino) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_ino differ. Cat: %x File: %x\n"), + statc.st_ino, statf.st_ino); + stat = JS_Differences; + } + break; + case 'p': /* permissions bits */ + if (statc.st_mode != statf.st_mode) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_mode differ. Cat: %x File: %x\n"), + statc.st_mode, statf.st_mode); + stat = JS_Differences; + } + break; + case 'n': /* number of links */ + if (statc.st_nlink != statf.st_nlink) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_nlink differ. Cat: %d File: %d\n"), + statc.st_nlink, statf.st_nlink); + stat = JS_Differences; + } + break; + case 'u': /* user id */ + if (statc.st_uid != statf.st_uid) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_uid differ. Cat: %d File: %d\n"), + statc.st_uid, statf.st_uid); + stat = JS_Differences; + } + break; + case 'g': /* group id */ + if (statc.st_gid != statf.st_gid) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_gid differ. Cat: %d File: %d\n"), + statc.st_gid, statf.st_gid); + stat = JS_Differences; + } + break; + case 's': /* size */ + if (statc.st_size != statf.st_size) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_size differ. Cat: %d File: %d\n"), + statc.st_size, statf.st_size); + stat = JS_Differences; + } + break; + case 'a': /* access time */ + if (statc.st_atime != statf.st_atime) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_atime differs\n")); + stat = JS_Differences; + } + break; + case 'm': + if (statc.st_mtime != statf.st_mtime) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_mtime differs\n")); + stat = JS_Differences; + } + break; + case 'c': /* ctime */ + if (statc.st_ctime != statf.st_ctime) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_ctime differs\n")); + stat = JS_Differences; + } + break; + case 'd': /* file size decrease */ + if (statc.st_size > statf.st_size) { + prt_fname(jcr); + Jmsg(jcr, M_INFO, 0, _(" st_size decrease. Cat: %d File: %d\n"), + statc.st_size, statf.st_size); + stat = JS_Differences; + } + break; + case '5': /* compare MD5 */ + Dmsg1(500, "set Do_MD5 for %s\n", jcr->fname); + do_MD5 = TRUE; + break; + case ':': + case 'V': + default: + break; + } + } + /* + * Got MD5 Signature from Storage daemon + * It came across in the Opts_MD5 field. + */ + } else if (stream == STREAM_MD5_SIGNATURE) { + Dmsg2(100, "stream=MD5 inx=%d fname=%s\n", file_index, jcr->fname); + /* + * When ever we get an MD5 signature is MUST have been + * preceded by an attributes record, which sets attr_file_index + */ + if (attr_file_index != file_index) { + Jmsg2(jcr, M_FATAL, 0, _("MD5 index %d not same as attributes %d\n"), + file_index, attr_file_index); + jcr->JobStatus = JS_ErrorTerminated; + return 0; + } + if (do_MD5) { + db_escape_string(buf, Opts_MD5, strlen(Opts_MD5)); + if (strcmp(buf, fdbr.MD5) != 0) { + prt_fname(jcr); + if (debug_level >= 10) { + Jmsg(jcr, M_INFO, 0, _(" MD5 not same. File=%s Cat=%s\n"), buf, fdbr.MD5); + } else { + Jmsg(jcr, M_INFO, 0, _(" MD5 differs.\n")); + } + stat = JS_Differences; + } + do_MD5 = FALSE; + } + } + jcr->jr.JobFiles = file_index; } if (n < 0) { Jmsg2(jcr, M_FATAL, 0, _("bdirdflags & FO_MD5) { -#ifdef really_needed - char MD5buf[50]; /* 24 bytes should do */ -#endif - MD5Final(signature, &md5c); - - /* First do Storage daemon */ bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_MD5_SIGNATURE); Dmsg1(10, "bfiled>stored:header %s\n", sd->msg); memcpy(sd->msg, signature, 16); sd->msglen = 16; bnet_send(sd); bnet_sig(sd, BNET_EOD); /* end of MD5 */ - -#ifdef really_needed - /* Now do Director (single record) */ - bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */ - bnet_fsend(dir, "%ld %d %s X", jcr->JobFiles, STREAM_MD5_SIGNATURE, - MD5buf); -#endif gotMD5 = 0; } #ifdef really_needed diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index 67eab1f68c..a083c0b1e0 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -45,14 +45,11 @@ void do_verify(JCR *jcr) set_find_options(jcr->ff, jcr->incremental, jcr->mtime); Dmsg0(10, "Start find files\n"); /* Subroutine verify_file() is called for each file */ - if (!find_files(jcr->ff, verify_file, (void *)jcr)) { - /****FIXME**** error termination */ - Dmsg0(0, "========= Error return from find_files\n"); - } + find_files(jcr->ff, verify_file, (void *)jcr); Dmsg0(10, "End find files\n"); - dir->msglen = 0; - bnet_send(dir); /* signal end attributes to director */ + bnet_sig(dir, BNET_EOD); /* signal end of data */ + if (jcr->big_buf) { free(jcr->big_buf); jcr->big_buf = NULL; @@ -71,7 +68,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) { char attribs[MAXSTRING]; int32_t n; - int fid; + int fid, stat; struct MD5Context md5c; unsigned char signature[16]; BSOCK *sd, *dir; @@ -128,14 +125,18 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) return 1; } - if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) { - ff_pkt->ff_errno = errno; - Jmsg(jcr, M_ERROR, -1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); - return 1; + + if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && + ff_pkt->statp.st_size > 0) { + if ((fid = open(ff_pkt->fname, O_RDONLY | O_BINARY)) < 0) { + ff_pkt->ff_errno = errno; + Jmsg(jcr, M_NOTSAVED, -1, _("Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + return 1; + } + } else { + fid = -1; } - Dmsg2(50, "opened %s fid=%d\n", ff_pkt->fname, fid); - Dmsg1(10, "bfiled: sending %s to Director\n", ff_pkt->fname); encode_stat(attribs, &ff_pkt->statp); jcr->JobFiles++; /* increment number of files sent */ @@ -144,48 +145,63 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) ff_pkt->VerifyOpts[0] = 'V'; ff_pkt->VerifyOpts[1] = 0; } + + + /* + * Send file attributes to Director + * File_index + * Stream + * Verify Options + * Filename (full path) + * Encoded attributes + * Link name (if type==FT_LNK) + * For a directory, link is the same as fname, but with trailing + * slash. For a linked file, link is the link. + */ /* Send file attributes to Director (note different format than for Storage) */ + Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname); if (ff_pkt->type == FT_LNK) { - dir->msglen = sprintf(dir->msg,"%d %d %s %s%c%s%c%s%c", jcr->JobFiles, + stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0); } else { - dir->msglen = sprintf(dir->msg,"%d %d %s %s%c%s%c%c", jcr->JobFiles, + stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs, 0, 0); } Dmsg2(20, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg); - bnet_send(dir); /* send to Director */ - + if (!stat) { + Jmsg(jcr, M_ERROR, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); + if (fid >= 0) { + close(fid); + } + return 0; + } - /* - * If MD5 is requested, read the file and compute the MD5 - * - */ - if (ff_pkt->flags & FO_MD5) { + /* If file opened, compute MD5 */ + if (fid >= 0 && ff_pkt->flags & FO_MD5) { char MD5buf[50]; /* 24 should do */ MD5Init(&md5c); - if (ff_pkt->type != FT_LNKSAVED && S_ISREG(ff_pkt->statp.st_mode) && - ff_pkt->statp.st_size > 0) { - while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) { - MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n); - jcr->JobBytes += n; - } - if (n < 0) { - Jmsg(jcr, M_ERROR, -1, _(" Error reading %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); - } + while ((n=read(fid, jcr->big_buf, jcr->buf_size)) > 0) { + MD5Update(&md5c, ((unsigned char *) jcr->big_buf), n); + jcr->JobBytes += n; + } + if (n < 0) { + Jmsg(jcr, M_WARNING, -1, _(" Error reading file %s: ERR=%s\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); } MD5Final(signature, &md5c); bin_to_base64(MD5buf, (char *)signature, 16); /* encode 16 bytes */ - dir->msglen = sprintf(dir->msg, "%d %d %s X", jcr->JobFiles, - STREAM_MD5_SIGNATURE, MD5buf); + Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, MD5buf); + bnet_fsend(dir, "%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_SIGNATURE, MD5buf, + jcr->JobFiles); Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg); - bnet_send(dir); /* send MD5 signature to Director */ } - close(fid); + if (fid >= 0) { + close(fid); + } return 1; } diff --git a/bacula/src/version.h b/bacula/src/version.h index df061e161c..1f1c3dab0d 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.19" #define VSTRING "1" -#define DATE "25 April 2002" -#define LSMDATE "25Apr02" +#define DATE "27 April 2002" +#define LSMDATE "27Apr02" /* Debug flags */ #define DEBUG 1 -- 2.39.5