+int idx_copy_insertsubject()
+/* copies old index file up to but not including msg, then adds a line with */
+/* 'sub' trimmed of reply indicators, then closes the new index and moves it*/
+/* to the name 'index'. Errors are dealt with directly, and if the routine */
+/* returns, it was successful. 'fatal' points to a program-specific error */
+/* string. Sub is not destroyed, but from is!!! */
+/* returns 1 if reply-indicators were found, 0 otherwise. */
+/* no terminal \n or \0 in any of the strallocs! */
+{
+ char *cp;
+ unsigned long idx;
+ int match;
+ int r;
+ unsigned int pos;
+
+ if (!stralloc_copys(&fnadir,"archive/")) die_nomem();
+ if (!stralloc_catb(&fnadir,strnum,fmt_ulong(strnum,outnum / 100)))
+ die_nomem();
+ if (!stralloc_copy(&fnif,&fnadir)) die_nomem();
+ if (!stralloc_copy(&fnifn,&fnif)) die_nomem();
+ if (!stralloc_cats(&fnif,"/index")) die_nomem();
+ if (!stralloc_cats(&fnifn,"/indexn")) die_nomem();
+ if (!stralloc_0(&fnif)) die_nomem();
+ if (!stralloc_0(&fnifn)) die_nomem();
+ if (!stralloc_0(&fnadir)) die_nomem();
+
+ /* may not exists since we run before ezmlm-send */
+ if (mkdir(fnadir.s,0755) == -1)
+ if (errno != error_exist)
+ strerr_die4x(111,FATAL,ERR_CREATE,fnadir.s,": ");
+
+ /* Open indexn */
+ fdindexn = open_trunc(fnifn.s);
+ if (fdindexn == -1)
+ strerr_die4x(111,FATAL,ERR_WRITE,fnifn.s,": ");
+
+ /* set up buffers for indexn */
+ substdio_fdbuf(&ssindexn,write,fdindexn,indexnbuf,sizeof(indexnbuf));
+
+ concatHDR(subject.s,subject.len,&lines,FATAL); /* make 1 line */
+ decodeHDR(lines.s,lines.len,&qline,charset.s,FATAL); /* decode mime */
+ r = unfoldHDR(qline.s,qline.len,&lines,charset.s,&dcprefix,1,FATAL);
+ /* trim mime */
+
+ fdindex = open_read(fnif.s);
+ if (fdindex == -1) {
+ if (errno != error_noent)
+ strerr_die4x(111,FATAL,ERR_OPEN, fnif.s, ": ");
+ } else {
+ substdio_fdbuf(&ssin,read,fdindex,inbuf,sizeof(inbuf));
+ for(;;) {
+ if (getln(&ssin,&qline,&match,'\n') == -1)
+ strerr_die4sys(111,FATAL,ERR_READ, fnif.s, ": ");
+ if (!match)
+ break;
+ pos = scan_ulong(qline.s,&idx);
+ if (!idx) /* "impossible!" */
+ strerr_die2x(111,FATAL,ERR_BAD_INDEX);
+ if (idx >= outnum)
+ break; /* messages always come in order */
+ if (substdio_put(&ssindexn,qline.s,qline.len) == -1)
+ die_indexn();
+ if (qline.s[pos] == ':') { /* has author line */
+ if (getln(&ssin,&qline,&match,'\n') == -1)
+ strerr_die4x(111,FATAL,ERR_READ, fnif.s, ": ");
+ if (!match && qline.s[0] != '\t') /* "impossible! */
+ strerr_die2x(111,FATAL,ERR_BAD_INDEX);
+ if (substdio_put(&ssindexn,qline.s,qline.len) == -1)
+ die_indexn();
+ }
+ }
+ close(fdindex);
+ }
+ if (!stralloc_copyb(&qline,strnum,fmt_ulong(strnum,outnum))) die_nomem();
+ if (!stralloc_cats(&qline,": ")) die_nomem(); /* ':' for new ver */
+ makehash(lines.s,lines.len,hash);
+ if (!stralloc_catb(&qline,hash,HASHLEN)) die_nomem();
+ if (!stralloc_cats(&qline," ")) die_nomem();
+ if (r & 1) /* reply */
+ if (!stralloc_cats(&qline,"Re: ")) die_nomem();
+ if (!stralloc_cat(&qline,&lines)) die_nomem();
+ if (!stralloc_cats(&qline,"\n\t")) die_nomem();
+ if (!stralloc_cat(&qline,&received)) die_nomem();
+ if (!stralloc_cats(&qline,";")) die_nomem();
+
+ concatHDR(from.s,from.len,&lines,FATAL);
+ mkauthhash(lines.s,lines.len,hash);
+
+ if (!stralloc_catb(&qline,hash,HASHLEN)) die_nomem();
+ if (!stralloc_cats(&qline," ")) die_nomem();
+
+ decodeHDR(cp,author_name(&cp,lines.s,lines.len),&from,charset.s,FATAL);
+ (void) unfoldHDR(from.s,from.len,&lines,charset.s,&dcprefix,0,FATAL);
+ if (!stralloc_cat(&qline,&lines)) die_nomem();
+
+ if (!stralloc_cats(&qline,"\n")) die_nomem();
+ if (substdio_put(&ssindexn,qline.s,qline.len) == -1) die_indexn();
+ if (substdio_flush(&ssindexn) == -1) die_indexn();
+ if (fsync(fdindexn) == -1) die_indexn();
+ if (fchmod(fdindexn,MODE_ARCHIVE | 0700) == -1) die_indexn();
+ if (close(fdindexn) == -1) die_indexn(); /* NFS stupidity */
+ if (rename(fnifn.s,fnif.s) == -1)
+ strerr_die4x(111,FATAL,ERR_MOVE,fnifn.s,": ");
+ return r;
+}
+
+void transferenc()
+{
+ if (flagcd) {
+ qmail_puts(&qq,"\nContent-Transfer-Encoding: ");
+ if (flagcd == 'Q')
+ qmail_puts(&qq,"Quoted-printable\n\n");
+ else
+ qmail_puts(&qq,"base64\n\n");
+ } else
+ qmail_puts(&qq,"\n\n");
+}
+
+void getcharset()
+{
+ if (getconf_line(&charset,"charset",0,FATAL,dir)) {
+ if (charset.len >= 2 && charset.s[charset.len - 2] == ':') {
+ if (charset.s[charset.len - 1] == 'B' ||
+ charset.s[charset.len - 1] == 'Q') {
+ flagcd = charset.s[charset.len - 1];
+ charset.s[charset.len - 2] = '\0';
+ }
+ }
+ } else
+ if (!stralloc_copys(&charset,TXT_DEF_CHARSET)) die_nomem();
+
+ if (!stralloc_0(&charset)) die_nomem();
+}
+