Main Program Callbacks All applications which use the c-client must have the following callbacks to handle events from c-client. Note that in any callback which involves a mail stream, the stream is locked and you can not recursively call c-client from the callback. This may also be true in callbacks which do not have a stream; in general, the rule is "do not call c-client, especially any mail_xxx() function, from a c-client callback". void mm_flags (MAILSTREAM *stream,unsigned long number); stream stream where event happened number message number This function is called when c-client manipulates the flags for the given message number. This alerts the application that it may need to inspect that message's flags to see if there are any interesting changes. void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status); stream stream where event happened mailbox mailbox name for this status status MAILSTATUS structure with message status This function is called when c-client reports status of a mailbox (generally as the result of a mail_status() function call). The returned MAILSTATUS structure has the following members: long flags; validity flags. These are the same as the SA_xxx option flags in the mail_status() call, and they indicate which of the other members of the MAILSTATUS structure have usable data (i.e. if SA_MESSAGES is not set, do not believe status->messages!!). unsigned long messages; number of messages if SA_MESSAGES unsigned long recent; number of recent messages if SA_RECENT unsigned long unseen; number of unseen messages if SA_UNSEEN unsigned long uidnext; next UID to be assigned if SA_UIDNEXT unsigned long uidvalidity; UID validity value if SA_UIDVALIDITY void mm_searched (MAILSTREAM *stream,unsigned long number); stream stream where event happened number message number This function is called to notify the main program that this message number matches a search (generally as the result of a mail_search_full() function call). void mm_exists (MAILSTREAM *stream,unsigned long number); stream stream where event happened number message number This function is called to notify the main program that there are this many messages in the mailbox. It is also used to notify the main program of new mail, by announcing a higher number than the main program was previously aware. void mm_expunged (MAILSTREAM *stream,unsigned long number); stream stream where event happened number message number This function is called to notify the main program that this message number has been expunged from the mail file and that all subsequent messages are now referenced by a message number one less than before. This implicitly decrements the number of messages in the mailbox. void mm_list (MAILSTREAM *stream,char delim,char *name,long attrib); stream stream where event happened delim hierarchy delimiter name mailbox name attrib mailbox attributes This function is called to notify the main program that this mailbox name matches a mailbox listing request (generally as the result of a mail_list() function call). The hierarchy delimiter is a character that separates out levels of hierarchy in mailbox names. The attributes are a bit mask with one of the following: LATT_NOINFERIORS it is not possible for there to be any hierarchy inferiors to this name (that is, this name followed by the hierarchy delimiter and additional name characters). LATT_NOSELECT this is not a mailbox name, just a hierarchy level, and it may not be opened by mail_open() LATT_MARKED this mailbox may have recent messages LATT_UNMARKED this mailbox does not have any recent messages void mm_lsub (MAILSTREAM *stream,char delim,char *name,long attrib); stream stream where event happened delim hierarchy delimiter name mailbox name attrib mailbox attributes This function is called to notify the main program that this mailbox name matches a subscribed mailbox listing request (generally as the result of a mail_lsub() function call). The hierarchy delimiter is a character that separates out levels of hierarchy in mailbox names. The attributes are a bit mask with one of the following: LATT_NOINFERIORS it is not possible for there to be any hierarchy inferiors to this name (that is, this name followed by the hierarchy delimiter and additional name characters). LATT_NOSELECT this is not a mailbox name, just a hierarchy level, and it may not be opened by mail_open() LATT_MARKED this mailbox may have recent messages LATT_UNMARKED this mailbox does not have any recent messages void mm_notify (MAILSTREAM *stream,char *string,long errflg); stream stream where event happened string message string errflg message error level This function is called to deliver a stream-oriented message event. This is the mechanism by which any IMAP response codes for any application (e.g. TRYCREATE) are delivered to the application. No newline is included in the string, so this function has to output its own. The message error level is one of the following: NIL normal operation. The text is `babble' that may be interesting to the user, e.g. the greeting message from a server. WARN A warning event. This event should be displayed to the user. Examples: a mailbox rewrite failed because of disk full, but the previous mailbox contents were recovered. ERROR An error event. This event should be displayed to the user, or at least logged someplace. This type of error shouldn't happen, and so should be called to the attention of support staff. Whatever happened has probably disrupted the user's work. Examples: an untagged BAD from an IMAP server. void mm_log (char *string,long errflg); string message string errflg message error level This function is called to deliver a log message. No newline is included in the string, so this function has to output its own. In general, it is intended that these messages are logged someplace, and possibly shown to the user. The message error level is one of the following: NIL normal operation. The text is `babble' that may be interesting to the user, e.g. "Expunged 3 messages". PARSE An RFC 822 parsing error. Since bogus headers are all-too-common in the real world, these can often be ignored on the "garbage in, garbage out" princple. However, since surprising results can be yielded when trying to parse garbage, this message should be logged somewhere so it can be figured out what happened. WARN A warning event. This event should be displayed to the user. It occurs when an error condition has happened, but c-client knows what to do to recover. Examples: "Can't open read-write, so opening read-only", "Empty mailbox", "Login failed, try again", "Waiting for mailbox to become unlocked", "IMAP protocol error". Although a user should be told about a warning, it's generally not necessary to interrupt the flow of her work (e.g. it's alright to display the warning in a scrolling window, but not necessary to require the user to do anything). ERROR An error event. This event should be displayed to the user, or at least logged someplace. This is a serious error condition occured that aborted the requested operation and possibly also aborted the mail stream. This ranges from normal error conditions such as "Can't open mailbox", "too many login failures, go away" to bizarre conditions such as "Apparent new mail appeared in the mailbox that doesn't look like mail, program aborting". Errors must be called to the user's attention, and probably should require some sort of acknowledgement (e.g. answering a modal panel) before the application proceeds. void mm_dlog (char *string); string message string This function is called to deliver a debugging telemetry message. No newline is included in the string, so this function has to output its own. This is called only when debugging is enabled. void mm_login (NETMBX *mb,char *user,char *pwd,long trial); mb parsed mailbox specification user pointer to where to return user name pwd pointer to where to return password trial number of prior login attempts This function is called to get a user name and password for the given network mailbox. It stores the user name and password in the strings pointed to by the appropriate arguments. The trial argument is the number of attempts to perform the login and is initially zero (e.g. for a default username and password login functionality). It is incremented for each subsequent trial until the maximum number of trials are made. void mm_critical (MAILSTREAM *stream); stream stream where event happened This function is called to alert the application that c-client is about to run some critical code on that stream that may result in a clobbered mail file if it is interrupted. It may be desirable to disable CTRL/C, etc. during this time. void mm_nocritical (MAILSTREAM *stream); stream stream where event happened This function is called to alert the application that c-client is no longer running critical code on that stream that may result in a clobbered mail file if it is interrupted. long mm_diskerror (MAILSTREAM *stream,long errcode,long serious); stream stream where event happened errcode OS error code for disk error serious non-zero if c-client can not undo the operation (and thus must retry to avoid mail file damage) This function is called to alert the application that the c-client has encountered an unrecoverable write error when trying to update the mail file. errcode contains the system error code. If serious is non-zero, then it is probable that the disk copy of the mailbox has been damaged. The return value from this function is the abort flag; if serious is zero and the abort flag is non-zero, the operation is aborted. If the abort flag is zero or if serious was non-zero, a return from this function will retry the failing operation. void mm_fatal (char *string); string message string This function is called from the fatal() routine in the operating system code to notify the main program that it is about to crash. The string contains a reason. At the very minimum, the main program should do something like mm_log (string,ERROR); and then return. No newline is included in the string, so this function has to output its own.