
/*
 * m_sync.c -- synchronize message sequences
 *
 * $Id$
 */

#include <h/mh.h>
#include <h/signals.h>


/*
 * decision logic
 *   1.  public and folder readonly: make it private
 *   2a. public: add it to the sequences file
 *   2b. private: add it to the profile
 */

void
m_sync (struct msgs *mp)
{
    int bits;
    register int i;
    register char *cp;
    char flags, attr[BUFSIZ], seq[BUFSIZ * 2];
    register FILE *fp;
    sigset_t set, oset;

    if (!(mp->msgflags & SEQMOD))
	return;
    mp->msgflags &= ~SEQMOD;

    m_getdefs ();
    sprintf (seq, "%s/%s", mp->foldpath, mh_seq);
    bits = FFATTRSLOT;
    fp = NULL;

    flags = mp->msgflags;
    if (mh_seq == NULL || *mh_seq == 0)
	mp->msgflags |= READONLY;

    for (i = 0; mp->msgattrs[i]; i++) {
	sprintf (attr, "atr-%s-%s", mp->msgattrs[i], mp->foldpath);
	if (mp->msgflags & READONLY
		|| mp->attrstats & (1 << (bits + i))) {
    priv: ;
	    if ((cp = m_seq(mp, mp->msgattrs[i])))
		m_replace (attr, cp);
	    else
		m_delete (attr);
	}
	else {
	    m_delete (attr);
	    if (!(cp = m_seq(mp, mp->msgattrs[i])))
		continue;
	    if (!fp) {
		if ((fp = fopen (seq, "w")) == NULL
			&& (unlink (seq) == NOTOK ||
			    (fp = fopen (seq, "w")) == NULL)) {
		    admonish (attr, "unable to write");
		    goto priv;
		}
		sigemptyset (&set);
		sigaddset(&set, SIGHUP);
		sigaddset(&set, SIGINT);
		sigaddset(&set, SIGQUIT);
		sigaddset(&set, SIGTERM);
		SIGPROCMASK (SIG_BLOCK, &set, &oset);
	    }
	    fprintf (fp, "%s: %s\n", mp->msgattrs[i], cp);
	}
    }

    if (fp) {
	fclose (fp);
	SIGPROCMASK (SIG_SETMASK, &oset, &set);  /* reset signal mask */
    }
    else
	if (!(mp->msgflags & READONLY))
	    unlink (seq);

    mp->msgflags = flags;
}
