📄 flocksim.c
字号:
mm_nocritical ((st == stream) ? stream : NIL); break; case 'D': /* mm_diskerror() */ st = (MAILSTREAM *) strtoul (event+1,&s,16); if (s && (*s++ == ' ')) { i = strtoul (s,&s,10); if (s && (*s++ == ' ')) { j = (long) strtoul (s,NIL,10); if (st == stream) /* let's hope it's on usable stream */ putc (mm_diskerror (stream,(long) i,j) ? '+' : '-',po); else if (j) { /* serious diskerror on slave-created stream */ mm_log ("Retrying disk write to avoid mailbox corruption!",WARN); sleep (5); /* give some time for it to clear up */ putc ('-',po); /* don't abort */ } else { /* recoverable on slave-created stream */ mm_log ("Error on disk write",ERROR); putc ('+',po); /* so abort it */ } fflush (po); /* force it out either way */ break; } } sprintf (tmp,"Invalid diskerror event arguments: %.500s",event); fatal (tmp); case 'F': /* mm_fatal() */ mm_fatal (event+1); break; default: /* random lossage */ sprintf (tmp,"Unknown event from execution process: %.500s",event); fatal (tmp); } } fclose (pi); fclose (po); /* done with the pipes */ /* get slave status */ grim_pid_reap_status (pid,NIL,&ret); if (ret & 0177) { /* signal or stopped */ sprintf (tmp,"Execution process terminated abnormally (%lx)",ret); mm_log (tmp,ERROR); ret = NIL; } else ret >>= 8; /* return exit code */ (*bn) (BLOCK_NONSENSITIVE,blockdata); } return ret; /* return status */}/* Safe driver calls *//* Safely delete mailbox * Accepts: driver to call under slave * MAIL stream * mailbox name to delete * Returns: T on success, NIL on failure */long safe_delete (DRIVER *dtb,MAILSTREAM *stream,char *mbx){ long ret = master (stream,NIL,NIL); if (lockslavep) exit ((*dtb->mbxdel) (stream,mbx)); return ret;}/* Safely rename mailbox * Accepts: driver to call under slave * MAIL stream * old mailbox name * new mailbox name (or NIL for delete) * Returns: T on success, NIL on failure */long safe_rename (DRIVER *dtb,MAILSTREAM *stream,char *old,char *newname){ long ret = master (stream,NIL,NIL); if (lockslavep) exit ((*dtb->mbxren) (stream,old,newname)); return ret;}/* Safely get status of mailbox * Accepts: driver to call under slave * MAIL stream * mailbox name * status flags * Returns: T on success, NIL on failure */long safe_status (DRIVER *dtb,MAILSTREAM *stream,char *mbx,long flags){ long ret = master (stream,NIL,NIL); if (lockslavep) exit ((*dtb->status) (stream,mbx,flags)); return ret;}/* Scan file for contents * Accepts: driver to call under slave * file name * desired contents * length of contents * length of file * Returns: NIL if contents not found, T if found */long safe_scan_contents (DRIVER *dtb,char *name,char *contents, unsigned long csiz,unsigned long fsiz){ long ret = master (NIL,NIL,NIL); if (lockslavep) exit (scan_contents (dtb,name,contents,csiz,fsiz)); return ret;}/* Safely copy message to mailbox * Accepts: driver to call under slave * MAIL stream * sequence * destination mailbox * copy options * Returns: T if success, NIL if failed */long safe_copy (DRIVER *dtb,MAILSTREAM *stream,char *seq,char *mbx,long flags){ mailproxycopy_t pc = (mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL); long ret = master (stream,NIL,NIL); if (lockslavep) { /* don't do proxycopy in slave */ if (pc) mail_parameters (stream,SET_MAILPROXYCOPY,(void *) slaveproxycopy); exit ((*dtb->copy) (stream,seq,mbx,flags)); } /* do any proxycopy in master */ if (lockproxycopy && pc) return (*pc) (stream,seq,mbx,flags); return ret;}/* Append package for slave */typedef struct append_data { int first; /* flag indicating first message */ char *flags; /* message flags */ char *date; /* message date */ char *msg; /* message text */ STRING message; /* message stringstruct */} APPENDDATA;/* Safely append message to mailbox * Accepts: driver to call under slave * MAIL stream * destination mailbox * append callback * data for callback * Returns: T if append successful, else NIL */long safe_append (DRIVER *dtb,MAILSTREAM *stream,char *mbx,append_t af, void *data){ long ret = master (stream,af,data); if (lockslavep) { APPENDDATA ad; ad.first = T; /* initialize initial append package */ ad.flags = ad.date = ad.msg = NIL; exit ((*dtb->append) (stream,mbx,slave_append,&ad)); } return ret;}/* Slave callbacks *//* Message exists (i.e. there are that many messages in the mailbox) * Accepts: MAIL stream * message number */void slave_exists (MAILSTREAM *stream,unsigned long number){ /* this event never passed by slaves */}/* Message expunged * Accepts: MAIL stream * message number */void slave_expunged (MAILSTREAM *stream,unsigned long number){ /* this event never passed by slaves */}/* Message status changed * Accepts: MAIL stream * message number */void slave_flags (MAILSTREAM *stream,unsigned long number){ /* this event never passed by slaves */}/* Mailbox status * Accepts: MAIL stream * mailbox name * mailbox status */void slave_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status){ int i,c; fprintf (slaveout,"S%lx %lu %lu %lu %lu %lu %lu ", (unsigned long) stream,status->flags,status->messages,status->recent, status->unseen,status->uidnext,status->uidvalidity,mailbox); /* yow! are we paranoid enough yet? */ for (i = 0; (i < 500) && (c = *mailbox++); ++i) switch (c) { case '\r': case '\n': /* newline in a mailbox name? */ c = ' '; default: putc (c,slaveout); } putc ('\n',slaveout); fflush (slaveout);}/* Notification event * Accepts: MAIL stream * string to log * error flag */void slave_notify (MAILSTREAM *stream,char *string,long errflg){ int i,c; fprintf (slaveout,"N%lx %lu ",(unsigned long) stream,errflg); /* prevent more than 500 bytes */ for (i = 0; (i < 500) && (c = *string++); ++i) switch (c) { case '\r': case '\n': /* or embedded newline */ c = ' '; default: putc (c,slaveout); } putc ('\n',slaveout); fflush (slaveout);}/* Log an event for the user to see * Accepts: string to log * error flag */void slave_log (char *string,long errflg){ int i,c; fprintf (slaveout,"L%lu ",errflg); /* prevent more than 500 bytes */ for (i = 0; (i < 500) && (c = *string++); ++i) switch (c) { case '\r': case '\n': /* or embedded newline */ c = ' '; default: putc (c,slaveout); } putc ('\n',slaveout); fflush (slaveout);}/* About to enter critical code * Accepts: stream */void slave_critical (MAILSTREAM *stream){ fprintf (slaveout,"C%lx\n",(unsigned long) stream); fflush (slaveout);}/* About to exit critical code * Accepts: stream */void slave_nocritical (MAILSTREAM *stream){ fprintf (slaveout,"X%lx\n",(unsigned long) stream); fflush (slaveout);}/* Disk error found * Accepts: stream * system error code * flag indicating that mailbox may be clobbered * Returns: abort flag */long slave_diskerror (MAILSTREAM *stream,long errcode,long serious){ char tmp[MAILTMPLEN]; int c; long ret = NIL; fprintf (slaveout,"D%lx %lu %lu\n",(unsigned long) stream,errcode,serious); fflush (slaveout); switch (c = getc (slavein)) { case EOF: /* pipe broken */ slave_fatal ("Pipe broken reading diskerror response"); case '+': /* user wants to abort */ ret = LONGT; case '-': /* no abort */ break; default: sprintf (tmp,"Unknown master response for diskerror: %c",c); slave_fatal (tmp); } return ret;}/* Log a fatal error event * Accepts: string to log * Does not return */void slave_fatal (char *string){ int i,c; syslog (LOG_ALERT,"IMAP toolkit slave process crash: %.500s",string); putc ('F',slaveout); /* prevent more than 500 bytes */ for (i = 0; (i < 500) && (c = *string++); ++i) switch (c) { case '\r': case '\n': /* newline in a mailbox name? */ c = ' '; default: putc (c,slaveout); } putc ('\n',slaveout); fflush (slaveout); abort (); /* die */}/* Append read buffer * Accepts: number of bytes to read * error message if fails * Returns: read-in string */static char *slave_append_read (unsigned long n,char *error){#if 0 unsigned long i;#endif int c; char *t,tmp[MAILTMPLEN]; char *s = (char *) fs_get (n + 1); s[n] = '\0';#if 0 /* This doesn't work on Solaris with GCC. I think that it's a C library * bug, since the problem only shows up if the application does fread() * on some other file */ for (t = s; n && ((i = fread (t,1,n,slavein)); t += i,n -= i);#else for (t = s; n && ((c = getc (slavein)) != EOF); *t++ = c,--n);#endif if (n) { sprintf(tmp,"Pipe broken reading %.100s with %lu bytes remaining",error,n); slave_fatal (tmp); } return s;}/* Append message callback * Accepts: MAIL stream * append data package * pointer to return initial flags * pointer to return message internal date * pointer to return stringstruct of message or NIL to stop * Returns: T if success (have message or stop), NIL if error */long slave_append (MAILSTREAM *stream,void *data,char **flags,char **date, STRING **message){ char tmp[MAILTMPLEN]; unsigned long n; int c; APPENDDATA *ad = (APPENDDATA *) data; /* flush text of previous message */ if (ad->flags) fs_give ((void **) &ad->flags); if (ad->date) fs_give ((void **) &ad->date); if (ad->msg) fs_give ((void **) &ad->msg); *flags = *date = NIL; /* assume no flags or date */ fputs ("A\n",slaveout); /* tell master we're doing append callback */ fflush (slaveout); switch (c = getc (slavein)) { /* what did master say? */ case '+': /* have message, get size of flags */ for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); if (c != ' ') { if (c == EOF) sprintf (tmp,"Pipe broken after flag size %lu",n); sprintf (tmp,"Missing delimiter after flag size %lu: %c",n,c); slave_fatal (tmp); } if (n) *flags = ad->flags = slave_append_read (n,"flags"); /* get size of date */ for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); if (c != ' ') { if (c == EOF) sprintf (tmp,"Pipe broken after date size %lu",n); else sprintf (tmp,"Missing delimiter after date size %lu: %c",n,c); slave_fatal (tmp); } if (n) *date = ad->date = slave_append_read (n,"date"); /* get size of message */ for (n = 0; isdigit (c = getc (slavein)); n *= 10, n += (c - '0')); if (c != ' ') { if (c == EOF) sprintf (tmp,"Pipe broken after message size %lu",n); sprintf (tmp,"Missing delimiter after message size %lu: %c",n,c); slave_fatal (tmp); } if (n) { /* make buffer for message */ ad->msg = slave_append_read (n,"message"); /* initialize stringstruct */ INIT (&ad->message,mail_string,(void *) ad->msg,n); ad->first = NIL; /* no longer first message */ *message = &ad->message; /* return message */ } else *message = NIL; /* empty message */ return LONGT; case '-': /* error */ *message = NIL; /* set stop */ break; case EOF: /* end of file */ slave_fatal ("Pipe broken reading append response"); default: /* unknown event */ sprintf (tmp,"Unknown master response for append: %c",c); slave_fatal (tmp); } return NIL; /* return failure */}/* Proxy copy across mailbox formats * Accepts: mail stream * sequence to copy on this stream * destination mailbox * option flags * Returns: T if success, else NIL */long slaveproxycopy (MAILSTREAM *stream,char *sequence,char *mailbox, long options){ fputs ("&\n",slaveout); /* redo copy as append */ fflush (slaveout); return NIL; /* failure for now */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -