QByteArray HyperBusReciever::messageEvent(const QByteArray &msg) { int index = msg.indexOf(":"); if( index == -1 ) return QByteArray(); QByteArray msg_prv = msg.mid(index+1); HyperBusRecord msg_record( msg_prv ); if( msg_record.count() == 0 ) return QByteArray(); p->last_pid = msg_record.takeFirst().toULongLong(); QByteArray res = callMessage(msg_record.toQByteArray()); return msg.mid(0,index+1)+res; }
QByteArray HyperBusReciever::callMessage(const QByteArray &msg) { HyperBusRecord msg_record( msg ); if( msg_record.count() == 0 ) return QByteArray(); quint64 map_id = msg_record.takeFirst().toULongLong(); if( !p->key_maps.contains(map_id) ) return QByteArray(); QVariantList vals; for( int i=0; i<10; i++ ) { if( i < msg_record.count() ) vals << HVariantConverter::decode(msg_record.at(i)); else vals << QVariant(); } const QString & key = p->key_maps.value(map_id); const QVariant & res_var = p->highway->call( key, vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7], vals[8], vals[9] ); return HVariantConverter::encode(res_var); }
static int restore_expunged(struct mailbox *mailbox, int mode, unsigned long *uids, unsigned nuids, time_t time_since, unsigned *numrestored, const char *extname) { struct index_record newrecord; annotate_state_t *astate = NULL; unsigned uidnum = 0; char oldfname[MAX_MAILBOX_PATH]; const char *fname; char *userid = mboxname_to_userid(mailbox->name); int r = 0; *numrestored = 0; struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED); const message_t *msg; while ((msg = mailbox_iter_step(iter))) { const struct index_record *record = msg_record(msg); /* still active */ if (!(record->internal_flags & FLAG_INTERNAL_EXPUNGED)) continue; if (mode == MODE_UID) { while (uidnum < nuids && record->uid > uids[uidnum]) uidnum++; if (uidnum >= nuids) continue; if (record->uid != uids[uidnum]) continue; /* otherwise we want this one */ } else if (mode == MODE_TIME) { if (record->last_updated < time_since) continue; /* otherwise we want this one */ } /* work on a copy */ newrecord = *record; /* duplicate the old filename */ fname = mailbox_record_fname(mailbox, record); xstrncpy(oldfname, fname, MAX_MAILBOX_PATH); /* bump the UID, strip the flags */ newrecord.uid = mailbox->i.last_uid + 1; newrecord.internal_flags &= ~FLAG_INTERNAL_EXPUNGED; if (unsetdeleted) newrecord.system_flags &= ~FLAG_DELETED; /* copy the message file */ fname = mailbox_record_fname(mailbox, &newrecord); r = mailbox_copyfile(oldfname, fname, 0); if (r) break; /* add the flag if requested */ if (addflag) { int userflag = 0; r = mailbox_user_flag(mailbox, addflag, &userflag, 1); if (r) break; newrecord.user_flags[userflag/32] |= 1<<(userflag&31); } /* and append the new record */ r = mailbox_append_index_record(mailbox, &newrecord); if (r) break; /* ensure we have an astate connected to the destination * mailbox, so that the annotation txn will be committed * when we close the mailbox */ r = mailbox_get_annotate_state(mailbox, newrecord.uid, &astate); if (r) break; /* and copy over any annotations */ r = annotate_msg_copy(mailbox, record->uid, mailbox, newrecord.uid, userid); if (r) break; if (verbose) printf("Unexpunged %s: %u => %u\n", extname, record->uid, newrecord.uid); /* mark the old one unlinked so we don't see it again */ struct index_record oldrecord = *record; oldrecord.internal_flags |= FLAG_INTERNAL_UNLINKED | FLAG_INTERNAL_NEEDS_CLEANUP; r = mailbox_rewrite_index_record(mailbox, &oldrecord); if (r) break; (*numrestored)++; } /* better get that seen to */ if (*numrestored) mailbox->i.options |= OPT_MAILBOX_NEEDS_UNLINK; mailbox_iter_done(&iter); free(userid); return r; }
static void list_expunged(const char *mboxname) { struct mailbox *mailbox = NULL; struct index_record *records = NULL; int alloc = 0; int num = 0; int i; int r; r = mailbox_open_irl(mboxname, &mailbox); if (r) { printf("Failed to open mailbox %s: %s", mboxname, error_message(r)); return; } /* first pass - read the records. Don't print until we release the * lock */ struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED); const message_t *msg; while ((msg = mailbox_iter_step(iter))) { const struct index_record *record = msg_record(msg); /* still active */ if (!(record->internal_flags & FLAG_INTERNAL_EXPUNGED)) continue; /* pre-allocate more space */ if (alloc <= num) { alloc += 64; records = xrealloc(records, sizeof(struct index_record) * alloc); } records[num] = *record; num++; } mailbox_iter_done(&iter); mailbox_unlock_index(mailbox, NULL); for (i = 0; i < num; i++) { const struct index_record *record = &records[i]; printf("UID: %u\n", record->uid); printf("\tSize: %u\n", record->size); printf("\tSent: %s", ctime(&record->sentdate)); printf("\tRecv: %s", ctime(&record->internaldate)); printf("\tExpg: %s", ctime(&record->last_updated)); if (mailbox_cacherecord(mailbox, record)) { printf("\tERROR: cache record missing or corrupt, " "not printing cache details\n\n"); continue; } printf("\tFrom: %.*s\n", cacheitem_size(record, CACHE_FROM), cacheitem_base(record, CACHE_FROM)); printf("\tTo : %.*s\n", cacheitem_size(record, CACHE_TO), cacheitem_base(record, CACHE_TO)); printf("\tCc : %.*s\n", cacheitem_size(record, CACHE_CC), cacheitem_base(record, CACHE_CC)); printf("\tBcc : %.*s\n", cacheitem_size(record, CACHE_BCC), cacheitem_base(record, CACHE_BCC)); printf("\tSubj: %.*s\n\n", cacheitem_size(record, CACHE_SUBJECT), cacheitem_base(record, CACHE_SUBJECT)); } free(records); mailbox_close(&mailbox); }
/* create a downgraded index file in cyrus.index. We don't copy back * expunged messages, sorry */ static int dump_index(struct mailbox *mailbox, int oldversion, struct seqset *expunged_seq, int first, int sync, struct protstream *pin, struct protstream *pout) { char oldname[MAX_MAILBOX_PATH]; const char *fname; int oldindex_fd = -1; indexbuffer_t headerbuf; indexbuffer_t recordbuf; char *hbuf = (char *)headerbuf.buf; char *rbuf = (char *)recordbuf.buf; int header_size; int record_size; int n, r; if (oldversion == 6) { header_size = 76; record_size = 60; } else if (oldversion == 7) { header_size = 76; record_size = 72; } else if (oldversion == 8) { header_size = 92; record_size = 80; } else if (oldversion == 9) { header_size = 96; record_size = 80; } else if (oldversion == 10) { header_size = 96; record_size = 88; } else { return IMAP_MAILBOX_BADFORMAT; } fname = mailbox_meta_fname(mailbox, META_INDEX); snprintf(oldname, MAX_MAILBOX_PATH, "%s.OLD", fname); oldindex_fd = open(oldname, O_RDWR|O_TRUNC|O_CREAT, 0666); if (oldindex_fd == -1) goto fail; downgrade_header(&mailbox->i, hbuf, oldversion, header_size, record_size); /* Write header - everything we'll say */ n = retry_write(oldindex_fd, hbuf, header_size); if (n == -1) goto fail; struct mailbox_iter *iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED); const message_t *msg; while ((msg = mailbox_iter_step(iter))) { const struct index_record *record = msg_record(msg); /* we have to make sure expunged records don't get the * file copied, or a reconstruct could bring them back * to life! It we're not creating an expunged file... */ if (record->system_flags & FLAG_EXPUNGED) { if (oldversion < 9) seqset_add(expunged_seq, record->uid, 1); continue; } /* not making sure exists matches, we do trust a bit */ downgrade_record(record, rbuf, oldversion); n = retry_write(oldindex_fd, rbuf, record_size); if (n == -1) goto fail; } mailbox_iter_done(&iter); close(oldindex_fd); r = dump_file(first, sync, pin, pout, oldname, "cyrus.index", NULL, 0); unlink(oldname); if (r) return r; /* create cyrus.expunge */ if (oldversion > 8 && mailbox->i.num_records > mailbox->i.exists) { int nexpunge = mailbox->i.num_records - mailbox->i.exists; fname = mailbox_meta_fname(mailbox, META_EXPUNGE); snprintf(oldname, MAX_MAILBOX_PATH, "%s.OLD", fname); oldindex_fd = open(oldname, O_RDWR|O_TRUNC|O_CREAT, 0666); if (oldindex_fd == -1) goto fail; header_set_num_records(hbuf, nexpunge); /* Write header - everything we'll say */ n = retry_write(oldindex_fd, hbuf, header_size); if (n == -1) goto fail; iter = mailbox_iter_init(mailbox, 0, ITER_SKIP_UNLINKED); while ((msg = mailbox_iter_step(iter))) { const struct index_record *record = msg_record(msg); /* ignore non-expunged records */ if (!(record->system_flags & FLAG_EXPUNGED)) continue; downgrade_record(record, rbuf, oldversion); n = retry_write(oldindex_fd, rbuf, record_size); if (n == -1) goto fail; } close(oldindex_fd); r = dump_file(first, sync, pin, pout, oldname, "cyrus.expunge", NULL, 0); unlink(oldname); if (r) return r; } return 0; fail: if (oldindex_fd != -1) close(oldindex_fd); unlink(oldname); return IMAP_IOERROR; }