<html> <head> <meta name="Content-Style" content="text/css"> </head> <body> <a href="#NAME">NAME</a><br> <a href="#SYNOPSIS">SYNOPSIS</a><br> <a href="##include <cyrus/imclient.h>">#include <cyrus/imclient.h></a><br> <a href="#DESCRIPTION">DESCRIPTION</a><br> <a href="#imclient_connect()">imclient_connect()</a><br> <a href="#imclient_servername()">imclient_servername()</a><br> <a href="#imclient_addcallback()">imclient_addcallback()</a><br> <a href="#imclient_processoneevent()">imclient_processoneevent()</a><br> <a href="#imclient_authenticate()">imclient_authenticate()</a><br> <a href="#EXAMPLES">EXAMPLES</a><br> <a href="#BUGS">BUGS</a><br> <a href="#SEE ALSO">SEE ALSO</a><br> <a href="#select(2)">select(2)</a><br> <a href="#KEYWORDS">KEYWORDS</a><br> <a href="#COPYRIGHT">COPYRIGHT</a><br> <!-- Creator : groff version 1.15 --> <!-- CreationDate: Mon Feb 3 16:31:15 2003 --> <!-- Total number of pages: 4 --> <!-- Page: 1 --> <!-- left margin: 100 --> <!-- right margin: 747 --> <a name="NAME"></a><h2>NAME</h2><p><font size=3>imclient library - authenticating callback interface to IMAP/IMSP servers</p> <a name="SYNOPSIS"></a><h2>SYNOPSIS</h2><a name="#include <cyrus/imclient.h>"></a><h2>#include <cyrus/imclient.h></h2> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="76.0433%"> <p><font size=3><B>int imclient_connect(struct imclient **</B><font size=3><I>imclient</I><font size=3><B>, const char *</B><font size=3><I>host</I><font size=3><B>, const char *</B><font size=3><I>port</I><font size=3><B>);</p> </B><p><font size=3><B>void imclient_close (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>);</p> </B><p><font size=3><B>void imclient_setflags(struct imclient *</B><font size=3><I>imclient</I><font size=3><B>, int</B><font size=3><I>flags</I><font size=3><B>);</p> </B><p><font size=3><B>void imclient_clearflags (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>, int</B><font size=3><I>flags</I><font size=3><B>);</p> </B><p><font size=3><B>char* imclient_servername (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>);</p> </B></td> <td valign="top" align="left" width="23.9567%"> </td> </tr> </table> <p><font size=3><B>void imclient_addcallback (struct imclient * imclient ,...);</p> </B> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="99.0726%"> <p><font size=3><B>void imclient_send (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>, void (*</B><font size=3><I>finishproc</I><font size=3><B>)(), void *</B><font size=3><I>finishrock</I><font size=3><B>, const char *</B><font size=3><I>fmt</I><font size=3><B>, ...);</p> </B><p><font size=3><B>void imclient_getselectinfo (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>, int *</B><font size=3><I>fd</I><font size=3><B>, int *</B> <font size=3><I>wanttowrite</I><font size=3><B>);</p> </B><p><font size=3><B>void imclient_processoneevent (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>);</p> </B><p><font size=3><B>int imclient_authenticate (struct imclient *</B><font size=3><I>imclient</I><font size=3><B>, struct sasl_client **</B><font size=3><I>availmech</I><font size=3><B>, const char *</B><font size=3><I>service</I><font size=3><B>, const<br> char *</B><font size=3><I>user</I><font size=3><B>, int</B> <font size=3><I>protallowed</I><font size=3><B>);</p> </B></td> <td valign="top" align="left" width="1.0000%"> </td> </tr> </table> <a name="DESCRIPTION"></a><h2>DESCRIPTION</h2> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="99.8454%"> <p><font size=3>The imclient library functions are distributed with Cyrus IMAP and IMSP. These functions are used for building<br> IMAP/IMSP client software. These functions handle Kerberos authentication and can set callbacks based on the<br> keyword in untagged replies or based on the command tag at the end of command replies.</p> <p><font size=3>Users must link with the -lcyrus switch, and must supply a function called <font size=3><I>fatal</I> <font size=3>to be called in case of any error<br> within <font size=3><I>libcyrus.a.</p> </I><p><font size=3>All of the <font size=3><B>imclient</B> <font size=3>functions begin with the prefix <font size=3><I>imclient</I> <font size=3>and takes an argument of type <font size=3><B>struct imclient *</B> <font size=3>as the<br> first argument which is initialized by <font size=3><B>imclient_connect</B> <font size=3>and freed by <font size=3><B>imclient_close.</p> </B><p><font size=3>See below for a description of each function.</p> </td> <td valign="top" align="left" width="1.0000%"> </td> </tr> </table> <a name="imclient_connect()"></a><h2>imclient_connect()</h2> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="4.6368%"> </td> <td valign="top" align="left" width="95.3632%"> <p><font size=3>Connects the client server to the host. If successful, it returns 0 and sets the imclient argument to a pointer to<br> an <font size=3><B>imclient</B> <font size=3>struct. The <font size=3><B>imclient</B> <font size=3>struct represents the current connection, flags, and callbacks. On failure,<br> the current <font size=3><B>errno</B> <font size=3>is returned if a system call failed, -1 is returned if the host name was not found, and -2 is<br> returned if the service name was not found.</p> </td> </tr> </table> <p><font size=3><B>imclient_close()</p> </B> <table width="100%" rules="none" frame="none" cols="3"> <tr valign="top" align="left"> <td valign="top" align="left" width="1.0000%"> </td> <td valign="top" align="left" width="98.6090%"> <p><font size=3><span style=" text-indent: 0.2700in;"></span>Closes and frees the <font size=3><B>imclient</B> <font size=3>connection.</p> <p><font size=3><B>imclient_setflags()<br> <span style=" text-indent: 0.2700in;"></span></B>Sets the flags specified by the <font size=3><B>flags</B> <font size=3>argument on the <font size=3><B>imclient</B> <font size=3>connection. Currently the only flag allowed is<br> <span style=" text-indent: 0.2700in;"></span><B>IMCLIENT_CONN_NONSYNCLITERAL</B> <font size=3>(this flag indicates that the server supports non-synchronizing<br> <span style=" text-indent: 0.2700in;"></span>literals described by the LITERAL+ extension).</p> </td> <td valign="top" align="left" width="1.0000%"> </td> </tr> </table> <p><font size=3><B>imclient_clearflags()<br> <span style=" text-indent: 0.3000in;"></span></B>Clears the flags specified by the <font size=3><B>flags</B> <font size=3>argument on the <font size=3><B>imclient</B> <font size=3>connection.</p> <a name="imclient_servername()"></a><h2>imclient_servername()</h2><p><span style=" text-indent: 0.3000in;"></span><font size=3>Returns a char * pointer to the name of the server connected to by <font size=3><B>imclient.</p> </B><a name="imclient_addcallback()"></a><h2>imclient_addcallback()</h2> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="4.6368%"> </td> <td valign="top" align="left" width="95.3632%"> <p><font size=3>Adds an untagged data callback to the <font size=3><B>imclient</B> <font size=3>connection. The function <font size=3><B>imclient_addcallback</B> <font size=3>takes call-<br> backs of the type <font size=3><B>imclient_proc_t</B> <font size=3>which is defined to be:<br> <span style=" text-indent: 1.2000in;"></span>typedef void imclient_proc_t (struct imclient *imclient, void *rock, struct imclient_reply<br> <span style=" text-indent: 1.2000in;"></span>*reply);</p> <p><font size=3>and <font size=3><B>struct imclient_reply *</B> <font size=3>is defined to be:</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3>struct imclient_reply {<br> <span style=" text-indent: 1.8200in;"></span>char *keyword;<br> <span style=" text-indent: 1.8200in;"></span>long msgno;<br> <span style=" text-indent: 1.8200in;"></span>char *text;<br> <span style=" text-indent: 1.2000in;"></span>};</p> <p><font size=3>After the first argument <font size=3><B>imclient,</B> <font size=3>there can be zero or more instances of the set of <font size=3><B>keyword, flags, proc,</B> <font size=3>and</p> </td> </tr> </table> <!-- Page: 2 --> <!-- left margin: 100 --> <!-- right margin: 750 --> <table width="100%" rules="none" frame="none" cols="3"> <tr valign="top" align="left"> <td valign="top" align="left" width="4.6154%"> </td> <td valign="top" align="left" width="94.9231%"> <p><font size=3><B>rock,</B> <font size=3>each adding or changing a single callback. Each instance adds or changes the callback for <font size=3><B>keyword.<br> </B>The argument, <font size=3><B>flags,</B> <font size=3>specifies information about the parsing of the untagged data. <font size=3><B>proc</B> <font size=3>and <font size=3><B>rock</B> <font size=3>specify the<br> callback function and rock to invoke when the untagged data is received. <font size=3><B>proc</B> <font size=3>may be a null pointer, in<br> which case no function is invoked. The callback function may not call the functions <font size=3><B>imclient_close(),<br> imclient_send(), imclient_eof(), imclient_processoneevent(),</B> <font size=3>or <font size=3><B>imclient_authenticate()</B> <font size=3>on the connec-<br> tion. The callback function may over write the text of untagged data.</p> </td> <td valign="top" align="left" width="1.0000%"> </td> </tr> </table> <p><font size=3><B>imclient_send()</p> </B> <table width="100%" rules="none" frame="none" cols="3"> <tr valign="top" align="left"> <td valign="top" align="left" width="4.6154%"> </td> <td valign="top" align="left" width="93.3846%"> <p><font size=3>Sends a new command to the <font size=3><B>imclient</B> <font size=3>connection. <font size=3><B>finishproc</B> <font size=3>and <font size=3><B>finnishrock</B> <font size=3>are the function and rock<br> called when the command completes. <font size=3><B>functionproc</B> <font size=3>may be a null pointer, in which case no callback is<br> made. The call back function may not call the functions <font size=3><B>imclient_close(), imclient_send(), imclient_eof(),<br> imclient_processoneevent(),</B> <font size=3>or <font size=3><B>imclient_authenticate()</B> <font size=3>on the connection. The argument, <font size=3><B>fmt</B> <font size=3>, is a print<br> like specification of the command. It must not include the tag as the tag is automatically added by<br> imclient_send(). The defined %-sequences are:</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3><B>%%</B> <font size=3>for %</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3><B>%a</B> <font size=3>for an IMAP atom</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3><B>%s</B> <font size=3>for an astring (which will be quoted or literalized as needed)</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3><B>%d</B> <font size=3>for a decimal</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3><B>%u</B> <font size=3>for an unsigned decimal</p> <p><span style=" text-indent: 1.2000in;"></span><font size=3><B>%v</B> <font size=3>for #astring (argument is a null-terminated array of <font size=3><B>char *</B> <font size=3>which are written as<br> <span style=" text-indent: 1.2000in;"></span>space separated astrings)</p> </td> <td valign="top" align="left" width="2.0000%"> </td> </tr> </table> <p><font size=3><B>imclient_getselectinfo()<br> <span style=" text-indent: 0.3000in;"></span></B>Gets the information for calling <font size=3><B>select(2). fd</B> <font size=3>is filled in with the file descriptor to <font size=3><B>select(2)</B> <font size=3>for read. <font size=3><B>want-<br> <span style=" text-indent: 0.3000in;"></span>towrite</B> <font size=3>is filled in with a nonzero value if select should be used for write as well.</p> <a name="imclient_processoneevent()"></a><h2>imclient_processoneevent()</h2><p><span style=" text-indent: 0.3000in;"></span><font size=3>Processes one input or output event on the <font size=3><B>imclient</B> <font size=3>connection.</p> <a name="imclient_authenticate()"></a><h2>imclient_authenticate()</h2> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="4.6154%"> </td> <td valign="top" align="left" width="95.3846%"> <p><font size=3>Authenticates the <font size=3><B>imclient</B> <font size=3>connection using one of the mechanisms in <font size=3><B>availmech.</B> <font size=3>The argument, <font size=3><B>user,</B> <font size=3>if not<br> NULL, specifies the user to authenticate as. If the user is NULL, the current user is used. The argument<br> <B>protallowed</B> <font size=3>is a bitmask of permissible protection mechanisms.</p> <p><font size=3>On success, 0 is returned. On failure (i.e., "BAD" keyboard, or no authentication mechanisms worked), 1 is<br> returned. On extreme failure (premature "OK"), 2 is returned.</p> </td> </tr> </table> <a name="EXAMPLES"></a><h2>EXAMPLES</h2> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="98.4615%"> <p><font size=3>The following code is a possible skeletion of <font size=3><B>imclient</B> <font size=3>that relies on Kerberos to do authentication. This code pre-<br> forms an IMAP CAPABILITY request and prints out the result.</p> <p><font size=3>struct sasl_client;<br> #include <cyrus/xmalloc.h> /* example uses xstrdup */<br> #include <cyrus/sasl.h><br> #include <cyrus/imclient.h><br> #include <stdio.h></p> <p><font size=3>extern struct sasl_client krb_sasl_client;</p> <p><font size=3>struct sasl_client *login_sasl_client[] = {</p> </td> <td valign="top" align="left" width="1.5385%"> </td> </tr> </table> <p><font size=3>&krb_sasl_client,<br> <span style=" text-indent: 0.1200in;"></span>NULL</p> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="37.3846%"> <p><font size=3>};<br> struct imclient *imclient;<br> char server[] = "cyrus.andrew.cmu.edu" ;<br> char port[] = "imap";</p> <p><font size=3>void fatal(char* message, int rc) {</p> </td> <td valign="top" align="left" width="62.6154%"> </td> </tr> </table> <p><font size=3>fprintf(stderr, "fatal error: %s\n", message);<br> <span style=" text-indent: 0.1200in;"></span>exit(rc);<br> }</p> <p><font size=3>static void callback_capability(struct imclient *imclient,<br> <span style=" text-indent: 2.0000in;"></span>void *rock,<br> </p> <!-- Page: 3 --> <!-- left margin: 100 --> <!-- right margin: 721 --> <p><span style=" text-indent: 2.0000in;"></span><font size=3>struct imclient_reply *reply) {</p> <table width="100%" rules="none" frame="none" cols="4"> <tr valign="top" align="left"> <td valign="top" align="left" width="1.1272%"> <p><font size=3>}</p> </td> <td valign="top" align="left" width="1.0000%"> </td> <td valign="top" align="left" width="43.6393%"> <p><font size=3>if (reply->text != NULL) {<br> <span style=" text-indent: 0.3800in;"></span>*((char**)rock) = xstrdup( reply->text );<br> }</p> </td> <td valign="top" align="left" width="54.4283%"> </td> </tr> </table> <table width="100%" rules="none" frame="none" cols="2"> <tr valign="top" align="left"> <td valign="top" align="left" width="58.2931%"> <p><font size=3>static void end_command (struct imclient *connection, void*<br> <span style=" text-indent: 1.5000in;"></span>rock, struct imclient_reply *inmsg) {<br> <span style=" text-indent: 0.1200in;"></span>(*(int*)rock)--;<br> }</p> <p><font size=3>main() {</p> </td> <td valign="top" align="left" width="41.7069%"> </td> </tr> </table> <table width="100%" rules="none" frame="none" cols="4"> <tr valign="top" align="left"> <td valign="top" align="left" width="1.1272%"> </td> <td valign="top" align="left" width="1.0000%"> </td> <td valign="top" align="left" width="73.7520%"> <p><font size=3>char* capability_string;<br> int nc;</p> <p><font size=3>if (imclient_connect(&imclient, server, port)) {<br> <span style=" text-indent: 0.3800in;"></span>fprintf(stderr,<br> <span style=" text-indent: 0.8800in;"></span>"error: Couldn't connect to %s %s\n",<br> <span style=" text-indent: 0.8800in;"></span>server, port);<br> <span style=" text-indent: 0.3800in;"></span>exit(1);<br> }</p> <p><font size=3>if (imclient_authenticate(imclient, login_sasl_client, "imap"<br> <span style=" text-indent: 1.5600in;"></span>/* service */,<br> <span style=" text-indent: 1.5600in;"></span>NULL /* user */, SASL_PROT_ANY)) {<br> <span style=" text-indent: 0.3800in;"></span>exit(1);<br> }</p> <p><font size=3>imclient_addcallback(imclient, "CAPABILITY",<br> <span style=" text-indent: 1.4100in;"></span>CALLBACK_NOLITERAL,<br> <span style=" text-indent: 1.4100in;"></span>callback_capability,<br> <span style=" text-indent: 1.4100in;"></span>&capability_string,<br> <span style=" text-indent: 1.4100in;"></span>NULL);</p> <p><font size=3>nc = 1;</p> <p><font size=3>imclient_send(imclient, end_command,<br> <span style=" text-indent: 0.9400in;"></span>(void*) &nc, "CAPABILITY");</p> <p><font size=3>while(nc > 0) {<br> <span style=" text-indent: 0.3800in;"></span>imclient_processoneevent(imclient);<br> }</p> <p><font size=3>if (strstr("LITERAL+", capability_string)) {<br> <span style=" text-indent: 0.3800in;"></span>imclient_setflags(imclient, IMCLIENT_CONN_NONSYNCLITERAL);<br> }</p> <p><font size=3>imclient_send(imclient, NULL, NULL, "LOGOUT");<br> imclient_close(imclient);</p> <p><font size=3>printf("capability text is: %s\n", capability_string);</p> <p><font size=3>free(capability_string);</p> </td> <td valign="top" align="left" width="24.3156%"> </td> </tr> <tr valign="top" align="left"> <td valign="top" align="left" width="1.1272%"> <p><font size=3>}</p> </td> <td valign="top" align="left" width="1.0000%"> </td> <td valign="top" align="left" width="73.7520%"> </td> <td valign="top" align="left" width="24.3156%"> </td> </tr> </table> <a name="BUGS"></a><h2>BUGS</h2><p><font size=3>No known bugs.</p> <a name="SEE ALSO"></a><h2>SEE ALSO</h2><p><font size=3><B>cyradm, imapd, imspd,</B> <font size=3>RFC2033 (IMAP LITERAL+ extension), RFC2060 (IMAP4rev1 specification), and<br> </p> <a name="select(2)"></a><h2>select(2)</h2> <!-- Page: 4 --> <!-- left margin: 100 --> <!-- right margin: 513 --> <a name="KEYWORDS"></a><h2>KEYWORDS</h2><p><font size=3>IMAP, ACAP, IMSP, Kerberos, Authentication</p> <a name="COPYRIGHT"></a><h2>COPYRIGHT</h2><p><font size=3>Copyright 1997-2002, Carnegie Mellon University. All Rights Reserved. See the source distribution for copying information.<br> </p> </body> </html>