diff options
Diffstat (limited to 'app/xlockmore/etc/chkmbox')
-rw-r--r-- | app/xlockmore/etc/chkmbox/Mail.xpm | 88 | ||||
-rw-r--r-- | app/xlockmore/etc/chkmbox/Makefile | 21 | ||||
-rw-r--r-- | app/xlockmore/etc/chkmbox/NoMail.xpm | 88 | ||||
-rw-r--r-- | app/xlockmore/etc/chkmbox/chkmbox.c | 63 | ||||
-rw-r--r-- | app/xlockmore/etc/chkmbox/chkmbox.cfg | 7 | ||||
-rw-r--r-- | app/xlockmore/etc/chkmbox/imapsocket.c | 553 | ||||
-rw-r--r-- | app/xlockmore/etc/chkmbox/imapsocket.h | 48 |
7 files changed, 868 insertions, 0 deletions
diff --git a/app/xlockmore/etc/chkmbox/Mail.xpm b/app/xlockmore/etc/chkmbox/Mail.xpm new file mode 100644 index 000000000..b90165876 --- /dev/null +++ b/app/xlockmore/etc/chkmbox/Mail.xpm @@ -0,0 +1,88 @@ +/* XPM */ +static char * image_name[] = { +"56 46 39 1", +" c #FFFFFBEEFFFF", +". c #B6DAAEBAB6DA", +"X c #082004100820", +"o c #9E799A699E79", +"O c #8E388A288E38", +"+ c #38E36DB6A699", +"@ c #BEFBB6DABEFB", +"# c #000000001861", +"$ c #A69979E78E38", +"% c #79E786179E79", +"& c #A699A289A699", +"* c #AEBAAEBAB6DA", +"= c #000008200820", +"- c #000000001040", +"; c #8E38861779E7", +": c #A6999E79A699", +"> c #71C679E78617", +", c #AEBA9E795965", +"< c #AEBAB2CACF3C", +"1 c #96589658AEBA", +"2 c #514471C68E38", +"3 c #FFFFF3CEFFFF", +"4 c #C71BBAEAC71B", +"5 c #CF3CC71BCF3C", +"6 c #EFBEF3CEF7DE", +"7 c #69A669A671C6", +"8 c #FFFFFFFFFFFF", +"9 c #AEBAA69971C6", +"0 c #AEBA61856185", +"q c #AEBAA699AEBA", +"w c #71C675D671C6", +"e c #5144A2894924", +"r c #861779E78617", +"t c #BEFBC30BCF3C", +"y c #69A68617BEFB", +"u c #A699A699A699", +"i c #965896589658", +"p c #F7DEB2CAAEBA", +"a c #51445555FFFF", +" .", +" ......................................................X", +" ...............oOO+O+O+O+OOoo.........................X", +" ........@....OO++++++++++X+X++o...@....@....@....@....X", +" o@..o@..o.@O++XoOo+#+#+@$%+OXXX+&...o@..o@..o..@o...o@X", +" ...@.*....O=+X+X+X.O-+=;%$OX+XXXXo*@....*...*@....*@..X", +" o.o.o@o@o+X+X+:oX+$+++$++.>,#+X+XXo.o@o@o@o@o.o@o@o.o.X", +" @*@..o.*+X+#+o.O@<*@+$*$*,1>$X+X+XXo.o*...*..o.*.*...oX", +" o.o.o@o+X+X++@2++O@.*<%@%1%-+>X+-+XXo@o@o@o@1.o@o@o@o@X", +" @..:*.+X+-+-++++$%..<..O<>,OO#+X+X+XX1.o*..o...o...o*.X", +" o.o.oOX+X+++++$%. .3..O.O.24O+XXXOX+X+o<o.1.o.o.1@1.o.X", +" .o.@.X+-+-+-++@ .......*1$O+X+OX++XXX+o.o...o.o.o...oX", +" o.o.++X++++$56@ . . ..O.O.7<X+XOXX+OXXX.:.o@1.o<o.o@1.X", +"3@1.o+#+-++O* . ......O@O%$+X+-+X+XX+.o.o.:.o.o<o.oX", +" o.1OX+o:O+$3. . . . ....O<;.O+X+X+X+-+XXo.1.o.o.o.o.o.X", +"3oo.++Xo:*5+ 8 . ......>9>$X+X+-+X+X+X+o.:o:.o:o.:ooX", +" o@%OX+O++3* .8@8. . ..O.O.%.-+-+-+-+-XXX+.o.o.o.o.:.o.X", +" o10O.X+<++ .8.8. .....@..O.O+-+X+X+X+X+XXoo:oo1oooooooX", +" o.+OOqX+q3+ .8.8.8.8.@O.O.O.X+X+-+-+XXOXX.1.o.o.1.o.1.X", +" oo%%*O.X@*@...*......*...%$O+X+X+-+XX XOXoo:oo:ooo1oooX", +" oq+;O@OO-+$%.. . .....O.O@w<O+-+X+-X XOoo.e+r<o:o4ooX", +"3oo+O1O..OX+X+=........<$eOOOOo+-+XX -%>++3#e$:ooooX", +" o:+>:.O.X+X+-+X+O.O.O.O.$<O0+2+o+X . X+4 @+*:ooo:X", +" :o+2,ooO+X+X+X+=+@..@O%$;O12o+;+X . . .. #e1:$:oX", +" O1+:O>o:X+-+X+-+X$X.O.O*>O+O+>+X . ... . t+1o1e1X", +"3oo+O$O%:+X+-+-+X+X+=+%$OO1>,1+X . .. .. #eo::oX", +" oo0+%+;$%+-+X+-+-+X+X++%+,+2+# ... .. .. @+$oeqX", +"3ooy+;1>%O++X+-+X+X+X+#>9>+$+X .. .. .. ->::oX", +" eqe$+$+%$>O+X+X+-+-+XO++++++@@..@................@.O0<X", +" ::q1=0%>,O>u+X+X+X+X+O#36 3 3 888 +>iX", +" $oOo+++O+2+OX+-+-+-++$X .. . . 888 upu X+:X", +" o%ooo#++>+O>+-+X+XoO%+X . . . ;u, -,OX", +" ,O%o%;+++$+O-+-+-o+$+>X +pp X+oX", +" :>o;:$+#++O++X+X++>+++X ppp ->OX", +" %1Oo%oO++++$#+Xu+;+$++# O%... X+:X", +" >,o$OOo$+#+++-++++++++X XOOX", +" O1Oo%o%qO+++++-++++++-X O;.O..O... X+1X", +" ;$e%;$,2$$++-+++++a+++X XOOX", +" $1$*%OO:%o1q++-+-+X+-+- $%..O.O;@8 X+oX", +" %O%O21O%%Oi2$$+-+-+-+-X 88 8 X$OX", +" ;,>o,$O1%>O:O%;&++X+X+X 88 8 X+>-", +"6%$%%>%O>,O0OO%$>O>$$OOX 88 8 X2,X", +" %o%$%OO%$:%%,>%1,1%;>OO++=X=XX=X=XX=XXXXXXXXX=XX=XXX+>-", +" i;$e%$%>O%;12OO%$;%1>92$O+O+O+O+O+O+O+O+O+O+O+O+O+O+OOX", +" $>9$>OOe$>OO01O%%$>,2>1;$>OO$>,>O$>,>O$>,2OO$>,>O$>9>1X", +".XXX--XX#--X-XXXXXXXX--XXX-X-X-X--X-X--X-X-X-X-X--X-XXXX"}; diff --git a/app/xlockmore/etc/chkmbox/Makefile b/app/xlockmore/etc/chkmbox/Makefile new file mode 100644 index 000000000..e310776d4 --- /dev/null +++ b/app/xlockmore/etc/chkmbox/Makefile @@ -0,0 +1,21 @@ +# +# Makefile for chkmbox +# + +CC= gcc +LN= gcc + +CFLAGS= -c -O2 -Wall + +XMBOX_OBJS= chkmbox.o imapsocket.o + +all: chkmbox + +.c.o: + $(CC) $(CFLAGS) $< + +chkmbox.o: imapsocket.h + +chkmbox: $(XMBOX_OBJS) + $(LN) -o $@ $(XMBOX_OBJS) + diff --git a/app/xlockmore/etc/chkmbox/NoMail.xpm b/app/xlockmore/etc/chkmbox/NoMail.xpm new file mode 100644 index 000000000..21c69d564 --- /dev/null +++ b/app/xlockmore/etc/chkmbox/NoMail.xpm @@ -0,0 +1,88 @@ +/* XPM */ +static char * image_name[] = { +"56 46 39 1", +" c #FFFFFBEEFFFF", +". c #B6DAAEBAB6DA", +"X c #082004100820", +"o c #9E799A699E79", +"O c #8E388A288E38", +"+ c #38E36DB6A699", +"@ c #BEFBB6DABEFB", +"# c #000000001861", +"$ c #A69979E78E38", +"% c #79E786179E79", +"& c #A699A289A699", +"* c #AEBAAEBAB6DA", +"= c #000008200820", +"- c #000000001040", +"; c #8E38861779E7", +": c #A6999E79A699", +"> c #71C679E78617", +", c #AEBA9E795965", +"< c #AEBAB2CACF3C", +"1 c #96589658AEBA", +"2 c #514471C68E38", +"3 c #FFFFF3CEFFFF", +"4 c #C71BBAEAC71B", +"5 c #CF3CC71BCF3C", +"6 c #EFBEF3CEF7DE", +"7 c #69A669A671C6", +"8 c #FFFFFFFFFFFF", +"9 c #AEBAA69971C6", +"0 c #AEBA61856185", +"q c #AEBAA699AEBA", +"w c #71C675D671C6", +"e c #5144A2894924", +"r c #861779E78617", +"t c #BEFBC30BCF3C", +"y c #69A68617BEFB", +"u c #A699A699A699", +"i c #965896589658", +"p c #F7DEB2CAAEBA", +"a c #51445555FFFF", +" .", +" ......................................................X", +" ...............oOO+O+O+O+OOoo.........................X", +" ........@....OO++++++++++X+X++o...@....@....@....@....X", +" o@..o@..o.@O++XoOo+#+#+@$%+OXXX+&...o@..o@..o..@o...o@X", +" ...@.*....O=+X+X+X.O-+=;%$OX+XXXXo*@....*...*@....*@..X", +" o.o.o@o@o+X+X+:oX+$+++$++.>,#+X+XXo.o@o@o@o@o.o@o@o.o.X", +" @*@..o.*+X+#+o.O@<*@+$*$*,1>$X+X+XXo.o*...*..o.*.*...oX", +" o.o.o@o+X+X++@2++O@.*<%@%1%-+>X+-+XXo@o@o@o@1.o@o@o@o@X", +" @..:*.+X+-+-++++$%..<..O<>,OO#+X+X+XX1.o*..o...o...o*.X", +" o.o.oOX+X+++++$%. .3..O.O.24O+XXXOX+X+o<o.1.o.o.1@1.o.X", +" .o.@.X+-+-+-++@ .......*1$O+X+OX++XXX+o.o...o.o.o...oX", +" o.o.++X++++$56@ . . ..O.O.7<X+XOXX+OXXX.:.o@1.o<o.o@1.X", +"3@1.o+#+-++O* . ......O@O%$+X+-+X+XX+.o.o.:.o.o<o.oX", +" o.1OX+o:O+$3. . . . ....O<;.O+X+X+X+-+XXo.1.o.o.o.o.o.X", +"3oo.++Xo:*5+ 8 . ......>9>$X+X+-+X+X+Xeo.:o:.o:o.:ooX", +" o@%OX+O++3* .8@8. . ..O.O.%.-+-+-+-+-XXXi.o.o.o.o.:.o.X", +" o10O.X+<++ .8.8. .....@..O.O+-+X+X+X+X+XXeo:oo1oooooooX", +" o.+OOqX+q3+ .8.8.8.8.@O.O.O.X+X+-+-+XXOX+.1.o.o.1.o.1.X", +" oo%%*O.X@*@...*......*...%$O+X+X+-+XXOX+Xiooo:2ooo:oooX", +" oq+;O@OO-+$%.. . .....O.O@w<O+-+X+-+-+XX+oo.oo:.@o@4ooX", +"3oo+O1O..OX+X+=........<$eOOOOo+-+XX-+-+X-o:io:o@::ooooX", +" o:+>:.O.X+X+-+X+O.O.O.O.$<O0+2+o+$+-XX+Xiqoo:o$q%<oi:oX", +" :o+2,ooO+X+X+X+=+@..@O%$;O12o+;+++X+X+XX-o:$o*>::oo:@oX", +" O1+:O>o:X+-+X+-+X$X.O.O*>O+O+>+%++++-X-:eoi:e::oe::oei-", +"3oo+O$O%:+X+-+-+X+X+=+%$OO1>,1++++++-++X-o:e:oreO$io:iqX", +" oo0+%+;$%+-+X+-+-+X+X++%+,+2+%++a+-a-++Xoq>>io:+>iOr>o-", +"3ooy+;1>%O++X+-+X+X+X+#>9>+$+i++++++i++->oeioqoo:eoqoioX", +" eqe$+$+%$>O+X+X+-+-+XO++++++@++++++++X.e<eoi<@oO.@.O0<X", +" ::q1=0%>,O>u+X+X+X+X+O#36 3 3 888 +>iX", +" $oOo+++O+2+OX+-+-+-++$X .. . . 888 upu X+:X", +" o%ooo#++>+O>+-+X+XoO%+X . . . ;u, -,OX", +" ,O%o%;+++$+O-+-+-o+$+>X +pp X+oX", +" :>o;:$+#++O++X+X++>+++X ppp ->OX", +" %1Oo%oO++++$#+Xu+;+$++# O%... X+:X", +" >,o$OOo$+#+++-++++++++X XOOX", +" O1Oo%o%qO+++++-++++++-X O;.O..O... X+1X", +" ;$e%;$,2$$++-+++++a+++X XOOX", +" $1$*%OO:%o1q++-+-+X+-+- $%..O.O;@8 X+oX", +" %O%O21O%%Oi2$$+-+-+-+-X 88 8 X$OX", +" ;,>o,$O1%>O:O%;&++X+X+X 88 8 X+>-", +"6%$%%>%O>,O0OO%$>O>$$OOX 88 8 X2,X", +" %o%$%OO%$:%%,>%1,1%;>OO++=X=XX=X=XX=XXXXXXXXX=XX=XXX+>-", +" i;$e%$%>O%;12OO%$;%1>92$O+O+O+O+O+O+O+O+O+O+O+O+O+O+OOX", +" $>9$>OOe$>OO01O%%$>,2>1;$>OO$>,>O$>,>O$>,2OO$>,>O$>9>1X", +".XXX--XX#--X-XXXXXXXX--XXX-X-X-X--X-X--X-X-X-X-X--X-XXXX"}; diff --git a/app/xlockmore/etc/chkmbox/chkmbox.c b/app/xlockmore/etc/chkmbox/chkmbox.c new file mode 100644 index 000000000..ea5f51957 --- /dev/null +++ b/app/xlockmore/etc/chkmbox/chkmbox.c @@ -0,0 +1,63 @@ +/****************************************************************************/ +/* + * xmbox.c -- Module to check for mail using an IMAP socket + * + * Logon to an IMAP server and check for unread messages. Return 0 if + * no RECENT or UNSEEN mail exists in the user's INBOX or > 0 if messages + * exist. + * + * Author: Michael P. Duane mduane@seanet.com + * Date: August 12, 1997 + * + * Copyright (c) 1997-98 by Michael P. Duane + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * + ****************************************************************************/ + +#include <stdio.h> +#include <fcntl.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> + +#include "imapsocket.h" + +char dftname [] = "chkmbox.cfg"; + +/*************************************************************************/ +int main( int argc, char **argv ) +{ +char *cfgname; +int msgnbr = -1; + + my_name = GetProgramName( *argv ); + + if ( argc >= 2 ) + cfgname = *(argv+1); + else + cfgname = dftname; + + RedirectErrLog(); + GetImapCfgInfo( cfgname ); + if ( !InitSocketAddr() ) + if ( !ServerLogin() ) /* Any errors here it will behave as "no mail" */ + msgnbr = CheckInbox(); + ServerLogout(); + + return( msgnbr ); + +} /* main */ diff --git a/app/xlockmore/etc/chkmbox/chkmbox.cfg b/app/xlockmore/etc/chkmbox/chkmbox.cfg new file mode 100644 index 000000000..439f20950 --- /dev/null +++ b/app/xlockmore/etc/chkmbox/chkmbox.cfg @@ -0,0 +1,7 @@ +# Configuration file for chkmbox + +Hostname = <mail host name> +port = 143 +User = <mail user name> +password = <mail user password> + diff --git a/app/xlockmore/etc/chkmbox/imapsocket.c b/app/xlockmore/etc/chkmbox/imapsocket.c new file mode 100644 index 000000000..6e46077cc --- /dev/null +++ b/app/xlockmore/etc/chkmbox/imapsocket.c @@ -0,0 +1,553 @@ +/****************************************************************************/ +/* + * imapsocket.c -- Module to check for mail using an IMAP socket + * + * Functions to logon to an IMAP server and check the user's INBOX for + * RECENT or UNSEEN mail. Errors may be logged to ~/.xsession-errors if + * stderr is redirected by a call to RedirectErrLog(), otherwise they are + * written to stderr. + * + * It is intended to be used as a set of library functions by a program + * that displays and icon, lights a keyboard LED or otherwise notifies + * a user that mail is waiting to be read. + * + * Author: Michael P. Duane mduane@seanet.com + * Date: August 12, 1997 + * + * Copyright (c) 1997-98 by Michael P. Duane + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * + ****************************************************************************/ + +#include <stdio.h> +#include <errno.h> +#include <ctype.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <fcntl.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> + +#ifndef FALSE +#define FALSE 0 +#define TRUE ~FALSE +#endif + +#define MAX_BUFFER_SIZE 8192 +#define MAX_BUFFER_LINES 32 + +#define SOCKET_ERROR (-1) + +char *my_name = ""; + +int fdImap = (-1); +struct sockaddr_in addrImap; + +int seq_num = 0; +char tag [ 8]; + +char hostname [64] = ""; +short port = 0; + +char user [64] = ""; +char passwd [64] = ""; + +char recv_buf [MAX_BUFFER_SIZE]; +char *line [MAX_BUFFER_LINES]; + +/****************************************************************************/ +/* + * GetProgramName() + * + * Extract just the basename from argv[0]. 'basename()' doesn't exist + * on all systems. + */ +char *GetProgramName( char *fullname ) +{ +char *name; + + return( name = ( (name = strrchr( fullname, '/' )) ? ++name : fullname ) ); + +} /* GetProgramName */ + +/****************************************************************************/ +/* + * RedirectErrLog() + * + * Redirect stderr to $HOME/.xsesson-errors. Create it if it doesn't + * exist, append to it if it does. + * + */ +int RedirectErrLog( void ) +{ +char *home; +char xsesserr [255]; +int mode = (O_CREAT | O_APPEND | O_WRONLY); +int fderr; + + if ( (home = getenv( "HOME" )) != NULL ) { + strcat( strcpy( xsesserr, home ), "/.xsession-errors" ); + if ( (fderr = open( xsesserr, mode, 0600 )) > 0 ) { + close( STDERR_FILENO ); + if ( dup( fderr ) == STDERR_FILENO ) + close( fderr ); + } + return( 0 ); + } + + return( -1 ); + +}/* RedirectErrLog */ + +/****************************************************************************/ +/* + * LogMessage() + * + * Prepend all error messages with my program name and log the corresponding + * errno description string where appropriate. + */ +void LogMessage( char *msg, int errval ) +{ + + if ( errval ) + fprintf( stderr, "%s: %s, %s\n", my_name, msg, strerror( errval ) ); + else + fprintf( stderr, "%s: %s\n", my_name, msg ); + +} /* LogMessage */ + +/****************************************************************************/ +/* + * ParseToken() + * + * Validate the "token = value" sequence to include a known token and + * a valid assignment operator. Store the value in a global on success. + */ +static void ParseToken( char *token, char *assign, char *value ) +{ +char errmsg [255]; +int i; + + for ( i=0; i< strlen( token ); i++ ) + *(token+i) = toupper( *(token+i) ); + + if ( strcmp( assign, "=" ) ) { + sprintf( errmsg, "\"%s\" missing assignment", token ); + LogMessage( errmsg, 0 ); + return; + } + + if ( !strcmp( token, "HOSTNAME" ) ) + strcpy( hostname, value ); + else if ( !strcmp( token, "PORT" ) ) + port = (short)strtol( value, (char **)NULL, 0 ); + else if ( !strcmp( token, "USER" ) ) + strcpy( user, value ); + else if ( !strcmp( token, "PASSWORD" ) ) + strcpy( passwd, value ); + else { + sprintf( errmsg, "Unexpected configuration token: \"%s\"", token ); + LogMessage( errmsg, 0 ); + } + +} /* ParseToken */ + +/****************************************************************************/ +static char *GetNextToken( char *str ) +{ + + return( strtok( str, " \t\n\r" ) ); + +} /* GetNextToken */ + +/****************************************************************************/ +/* + * GetImapCfgInfo() + * + * Reads the program configuration file looking for assignments of the + * form "token = value". '#' begins a comment that contiues to EOL. + */ +int GetImapCfgInfo( char *cfgfile ) +{ +FILE *cfg; +char txtbuf [512]; +char *txt; +char *tok; +char *assign; +char *val; + + if ( (cfg = fopen( cfgfile, "r" )) != NULL ) { + do { + if ( (txt = fgets( txtbuf, sizeof( txtbuf ), cfg )) != NULL) { + if ( (tok = GetNextToken( txt )) ) { + assign = val = NULL; + if ( strlen( tok ) ) { + if ( strchr( tok, '#' ) ) + continue; + assign = GetNextToken( NULL ); + val = GetNextToken( NULL ); + GetNextToken( NULL ); /* strip to eol */ + } + if ( assign && val ) + ParseToken( tok, assign, val ); + } + } + } while( !feof( cfg ) ); + fclose( cfg ); + } + else { + LogMessage( cfgfile, errno ); + return( -1 ); + } + + return( 0 ); + +} /* GetImapCfgInfo */ + +/****************************************************************************/ +/* + * InitSocketAddr() + * + * Setup and validate the host/port address for the IMAP socket + */ + +int InitSocketAddr( void ) +{ +struct hostent *host_info; +char addr_str [ 32]; + + if ( (host_info = gethostbyname( hostname )) == NULL ) { + LogMessage( "Host name error", errno ); + return( -1 ); + } + + sprintf( addr_str,"%u.%u.%u.%u", + (unsigned char)host_info->h_addr_list[0][0], + (unsigned char)host_info->h_addr_list[0][1], + (unsigned char)host_info->h_addr_list[0][2], + (unsigned char)host_info->h_addr_list[0][3] + ); + + addrImap.sin_family = PF_INET; + addrImap.sin_addr.s_addr = inet_addr( addr_str ); + addrImap.sin_port = htons( port ); + + if ( addrImap.sin_addr.s_addr == INADDR_NONE ) { + LogMessage( "Socket Address Error", errno ); + return( -1 ); + } + + return( 0 ); + +} /* InitSocketAddr */ + +/****************************************************************************/ +/* + * ConnectSocket() + * + * Open and connect to the IMAP socket + */ + +static int ConnectSocket( struct sockaddr_in *addrImap ) +{ + + if ( addrImap->sin_addr.s_addr == INADDR_NONE ) { + LogMessage( "Socket Address Error", errno ); + return( -1 ); + } + + if ( (fdImap = socket( AF_INET, SOCK_STREAM, 0 )) == SOCKET_ERROR ) { + LogMessage( "Error opening socket", errno ); + return( -1 ); + } + + if ( connect( fdImap, (struct sockaddr *)addrImap, + sizeof( struct sockaddr )) == SOCKET_ERROR ) { + close( fdImap ); + fdImap = (-1); + LogMessage( "Socket Connection error", errno ); + return( -1 ); + } + + return( 0 ); + +} /* ConnectSocket */ + +/****************************************************************************/ +/* + * OpenImapSocket() + * + * Connect to the IMAP socket and make sure the IMAP service responds. + */ + +static int OpenImapSocket( struct sockaddr_in *addrImap ) +{ +int i; + + if ( ConnectSocket( addrImap ) ) + return( -1 ); + + seq_num = 0; + memset( recv_buf, 0, sizeof( recv_buf ) ); + + for( i=0; i<MAX_BUFFER_LINES; i++ ) + line[i] = NULL; + + if ( recv( fdImap, (char *)recv_buf, + sizeof( recv_buf ), 0 ) == SOCKET_ERROR ) { + close( fdImap ); + fdImap = (-1); + LogMessage( "Socket revc error", errno ); + return( -1 ); + } + + if ( strncmp( "* OK", recv_buf, 4 ) == 0 ) { + return( 0 ); + } + else { + close( fdImap ); + LogMessage( "IMAP service timeout", 0 ); + return( -1 ); + } + +} /* OpenImapSocket */ + +/****************************************************************************/ +/* + * ImapCmd() + * + * Send an IMAP command to the socket. The "tag" is used by the IMAP + * protocol to match responses to commands. + */ + +static int ImapCmd( char *fmt, ... ) +{ +char cmd_buf [128]; +va_list argp; + + sprintf( tag, "A%3.3d", ++seq_num ); + sprintf( cmd_buf, "%s ", tag ); + + va_start( argp, fmt ); + vsprintf( &cmd_buf[ strlen( cmd_buf ) ], fmt, argp ); + va_end( argp ); + + if ( send( fdImap, cmd_buf, strlen( cmd_buf ), 0 ) == SOCKET_ERROR ) { + close( fdImap ); + fdImap = (-1); + LogMessage( "IMAP send error", errno ); + return( -1 ); + } + + return( 0 ); + +} /* ImapCmd */ + +/****************************************************************************/ +/* + * GetImapMsg() + * + * Get an IMAP response and check for the tag and for the "OK". + */ + +static int GetImapMsg( char *buf, int size ) +{ +char tmp [16]; + + memset( buf, 0, size ); + + if ( recv( fdImap, (char *)buf, size, 0 ) == SOCKET_ERROR ) { + close( fdImap ); + fdImap = (-1); + LogMessage( "IMAP read error", errno ); + return( -1 ); + } + + sprintf( tmp, "%s OK", tag ); + + if ( strstr( buf, tmp ) != NULL ) + return( 0 ); + else { + LogMessage( "IMAP command error", 0 ); + return( -1 ); + } + +} /* GetImapMsg */ + +/****************************************************************************/ +/* + * ServerLogin( void ) + * + * Start the IMAP session to check for new mail + * RETURN: 0 for success or -1 for failure + */ + +int ServerLogin( void ) +{ +int status = -1; + + if ( !OpenImapSocket( &addrImap ) ) { + if ( !ImapCmd( "LOGIN %s %s\n", user, passwd ) ) { + if ( GetImapMsg( recv_buf, sizeof( recv_buf ) ) ) + LogMessage( "IMAP LOGIN error", 0 ); + else + status = 0; + } + } + + return( status ); + +} /* ServerLogin */ + +/****************************************************************************/ +/* + * ServerLogout() + * + * Close the IMAP session + * RETURN: none + */ + +void ServerLogout( void ) +{ + + if ( !ImapCmd( "LOGOUT\n" ) ) + GetImapMsg( recv_buf, sizeof( recv_buf ) ); + + close( fdImap ); + +} /* ServerLogout */ + +/****************************************************************************/ +/* + * ParseBufLines() + * + * Parse the response into single lines. + * + * ARGS: b - raw response buffer + * l - an array char * for the individual lines + * + * RETURN: the number of lines + * + */ + +static int ParseBufLines( char *b, char *l[] ) +{ +int i; + + for ( i=0; i<MAX_BUFFER_LINES; i++ ) + l[i] = NULL; + + if ( (l[0] = strtok( b, "\n" )) == NULL ) + return( 0 ); + + for ( i=1; i<MAX_BUFFER_LINES; i++ ) { + if ( (l[i] = strtok( NULL, "\n" )) == NULL ) + return( i ); + } + + return( MAX_BUFFER_LINES ); + +} /* ParseBufLines */ + +/****************************************************************************/ +/* + * CheckRecent() + * + * This routine looks through an array of lines for the "RECENT" response + * and returns the number of "RECENT" message. If there are no "RECENT" + * messages it then checks for any "UNSEEN" messages. + * + * ARGS: b - raw response buffer + * l - an array char * for the individual lines + * + * RETURN: number. 0 is no messages. For messages found with the + * RECENT command number is the count of RECENT messages. For + * messages found with the UNSEEN command 'number' is the + * message number of an UNSEEN message. + */ + +static int CheckRecent( char *b, char *l[] ) +{ +int i; +int num_msg = -1; + +/* + * Check for new messages that have arrived since the last time we looked + */ + if ( !GetImapMsg( recv_buf, sizeof( recv_buf ) ) ) { + if ( ParseBufLines( b, l ) > 0 ) { + for( i=0; i<MAX_BUFFER_LINES; i++ ) { + if ( strstr( l[i], "RECENT" ) != NULL ) + break; + } + sscanf( l[i], "%*s %d %*s", &num_msg ); + } + } +/* + * If nothing new has arrived check for any messages that may still be + * in the mailbox but have not been read + */ + if ( num_msg <= 0 ) { + if ( !ImapCmd( "SEARCH UNSEEN\n" ) ) { + if ( !GetImapMsg( recv_buf, sizeof( recv_buf ) ) ) { + if ( ParseBufLines( b, l ) > 0 ) { + for( i=0; i<MAX_BUFFER_LINES; i++ ) { + if ( strstr( l[i], "SEARCH" ) != NULL ) + break; + } + sscanf( l[i], "%*s %*s %d", &num_msg ); + } + } + } + } +/* + * Any non-zero value means there are messages that have not been read. + * This is not a count or an index to the newest message + */ + return( num_msg ); + +} /* CheckRecent */ + +/****************************************************************************/ +/* + * CheckInbox() + * + * This is the IMAP session to check for new mail + * + * RETURN: 1 for no messages, 0 if messages exist. /* Inverted by DAB */ + */ + +int CheckInbox( void ) +{ +int status = -1; + + if ( fdImap < 0 ) { + if ( ServerLogin() ) + return( !status ); /* Inverted by DAB */ + } + + if ( !ImapCmd( "EXAMINE INBOX\n" ) ) + status = CheckRecent( recv_buf, line ); + + return( !status ); /* Inverted by DAB */ + +} /* CheckInbox */ + +/****************************************************************************/ +/* end of imapsocket.c */ diff --git a/app/xlockmore/etc/chkmbox/imapsocket.h b/app/xlockmore/etc/chkmbox/imapsocket.h new file mode 100644 index 000000000..506eb76e4 --- /dev/null +++ b/app/xlockmore/etc/chkmbox/imapsocket.h @@ -0,0 +1,48 @@ +/****************************************************************************/ +/* + * imapsocket.h -- Module to check for mail using an IMAP socket + * + * Functions to logon to an IMAP server and check the user's INBOX for + * RECENT or UNSEEN mail. Errors may be logged to ~/.xsession-errors if + * stderr is redirected by a call to RedirectErrLog(), otherwise they are + * written to stderr. + * + * It is intended to be used as a set of library functions by a program + * that displays and icon, lights a keyboard LED or otherwise notifies + * a user that mail is waiting to be read. + * + * Author: Michael P. Duane mduane@seanet.com + * Date: August 12, 1997 + * + * Copyright (c) 1997-98 by Michael P. Duane + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, + * provided that the above copyright notice appear in all copies and that + * both that copyright notice and this permission notice appear in + * supporting documentation. + * + * This file is provided AS IS with no warranties of any kind. The author + * shall have no liability with respect to the infringement of copyrights, + * trade secrets or any patents by this file or any part thereof. In no + * event will the author be liable for any lost revenue or profits or + * other special, indirect and consequential damages. + * + * Revision History: + * + ****************************************************************************/ + +#ifndef IMAPSOCKET_H +#define IMAPSOCKET_H + +extern char *my_name; + +int RedirectErrLog( void ); +char *GetProgramName( char *fullname ); +int GetImapCfgInfo( char *cfgfile ); +int InitSocketAddr( void ); +int ServerLogin( void ); +void ServerLogout( void ); +int CheckInbox( void ); + +#endif /* IMAPSOCKET_H */ |