+ } else { /* Something is wrong FileId == 0 */
+ Jmsg(jcr, M_WARNING, 0, "Illegal FileId in update attribute: FileId=0 Stream=%d fname=%s\n",
+ ar->Stream, ar->fname);
+ }
+ }
+ }
+}
+
+/*
+ * Update File Attributes in the catalog with data
+ * sent by the Storage daemon.
+ */
+void catalog_update(JCR *jcr, BSOCK *bs)
+{
+ if (!jcr->pool->catalog_files) {
+ return; /* user disabled cataloging */
+ }
+ if (jcr->is_job_canceled()) {
+ goto bail_out;
+ }
+ if (!jcr->db) {
+ POOLMEM *omsg = get_memory(bs->msglen+1);
+ pm_strcpy(omsg, bs->msg);
+ bs->fsend(_("1994 Invalid Catalog Update: %s"), omsg);
+ Jmsg1(jcr, M_FATAL, 0, _("Invalid Catalog Update; DB not open: %s"), omsg);
+ free_memory(omsg);
+ goto bail_out;
+ }
+ update_attribute(jcr, bs->msg, bs->msglen);
+
+bail_out:
+ if (jcr->is_job_canceled()) {
+ jcr->cached_attribute = false;
+ cancel_storage_daemon_job(jcr);
+ }
+}
+
+/*
+ * Update File Attributes in the catalog with data read from
+ * the storage daemon spool file. We receive the filename and
+ * we try to read it.
+ */
+bool despool_attributes_from_file(JCR *jcr, const char *file)
+{
+ bool ret=false;
+ int32_t pktsiz;
+ ssize_t nbytes;
+ ssize_t size = 0;
+ int32_t msglen; /* message length */
+ POOLMEM *msg = get_pool_memory(PM_MESSAGE);
+ FILE *spool_fd=NULL;
+ int32_t recnum = 0;
+
+ Dmsg1(100, "Begin despool_attributes_from_file\n", file);
+
+ if (jcr->is_job_canceled() || !jcr->pool->catalog_files || !jcr->db) {
+ goto bail_out; /* user disabled cataloging */
+ }
+
+ spool_fd = bfopen(file, "rb");
+ //Dmsg1(000, "Open attr read file=%s\n", file);
+ if (!spool_fd) {
+ Dmsg0(100, "cancel despool_attributes_from_file\n");
+ /* send an error message */
+ goto bail_out;
+ }
+#if defined(HAVE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
+ posix_fadvise(fileno(spool_fd), 0, 0, POSIX_FADV_WILLNEED);
+#endif
+
+ /*
+ * We read the attributes file or stream from the SD. It should
+ * be in the following format:
+ *
+ * 1. 4 bytes representing the record length
+ * 2. An attribute string starting with: UpdCat Job=nnn FileAttributes ...
+ */
+ for ( ;; ) {
+ nbytes = fread((char *)&pktsiz, 1, sizeof(int32_t), spool_fd);
+ if (nbytes == 0) { /* EOF */
+ break;
+ }
+ if (nbytes != sizeof(int32_t)) {
+ Dmsg2(000, "Error: attr read status=%lld addr=%lld\n", nbytes, ftello(spool_fd));
+ break;
+ }
+ size += sizeof(int32_t);
+ msglen = ntohl(pktsiz);
+ if (msglen > 10000000) {
+ Qmsg1(jcr, M_FATAL, 0, _("fread attr spool error. Wanted %ld bytes, maximum permitted 10000000 bytes\n"), msglen);
+ goto bail_out;
+ }
+ if (msglen > 0) {
+ if (msglen > (int32_t)sizeof_pool_memory(msg)) {
+ msg = realloc_pool_memory(msg, msglen + 1);
+ }
+ nbytes = fread(msg, 1, msglen, spool_fd);
+ recnum++;
+ if (nbytes > 0 && strncmp(msg, "UpdCat Job", 10) != 0) {
+ Dmsg3(000, "Error: recnum=%ld nbytes=%lld msg=%s\n", recnum, nbytes, msg);
+ }
+ if (nbytes != (ssize_t)msglen) {
+ berrno be;
+ boffset_t size;
+ size = ftello(spool_fd);
+ Dmsg4(000, "Error at size=%lld record %ld: got nbytes=%lld, want msglen=%ld\n", size, recnum, (int32_t)nbytes, msglen);
+ Qmsg3(jcr, M_FATAL, 0, _("fread attr spool error. Wanted %ld bytes but got %lld ERR=%s\n"),
+ msglen, nbytes, be.bstrerror());
+ goto bail_out;