Back to index

citadel  8.12
citadel_ipc.h
Go to the documentation of this file.
00001 
00002 #define       UDS                  "_UDS_"
00003 #ifdef __CYGWIN__
00004 #define DEFAULT_HOST        "localhost"
00005 #else
00006 #define DEFAULT_HOST        UDS
00007 #endif
00008 #define DEFAULT_PORT        "504"
00009 
00010 #include "sysdep.h"
00011 #ifdef HAVE_PTHREAD_H
00012 #include <pthread.h>
00013 #endif
00014 #ifdef HAVE_OPENSSL
00015 #include <openssl/ssl.h>
00016 #include <openssl/err.h>
00017 #include <openssl/rand.h>
00018 #endif
00019 
00020 #include "server.h"
00021 
00022 #ifdef __cplusplus
00023 extern "C" {
00024 #endif
00025 
00026 /* Quick and dirty hack; we don't want to use malloc() in C++ */
00027 #ifdef __cplusplus
00028 #define ialloc(t)    new t()
00029 #define ifree(o)     delete o
00030 #else
00031 #define ialloc(t)    malloc(sizeof(t))
00032 #define ifree(o)     free(o);
00033 #endif
00034 
00035 struct CtdlServInfo {
00036        int pid;
00037        char nodename[32];
00038        char humannode[64];
00039        char fqdn[64];
00040        char software[64];
00041        int rev_level;
00042        char site_location[64];
00043        char sysadm[64];
00044        char moreprompt[256];
00045        int ok_floors;
00046        int paging_level;
00047        int supports_qnop;
00048        int supports_ldap;
00049        int newuser_disabled;
00050        char default_cal_zone[256];
00051        double load_avg;
00052        double worker_avg;
00053        int thread_count;
00054        int has_sieve;
00055        int fulltext_enabled;
00056        char svn_revision[256];
00057        int guest_logins;
00058 };
00059 
00060 /*
00061  * This class is responsible for the server connection
00062  */
00063 typedef struct _CtdlIPC {
00064        struct CtdlServInfo ServInfo;      /* The server info for this connection */
00065 
00066 #if defined(HAVE_OPENSSL)
00067        SSL *ssl;                   /* NULL if not encrypted, non-NULL otherwise */
00068 #endif
00069 
00070 #if defined(HAVE_PTHREAD_H)
00071        pthread_mutex_t mutex;             /* Fast mutex, call CtdlIPC_lock() or CtdlIPC_unlock() to use */
00072 #endif
00073 
00074        int sock;                   /* Socket for connection to server, or -1 if not connected */
00075        int isLocal;                /* 1 if server is local, 0 otherwise or if not connected */
00076        int downloading;            /* 1 if a download is open on the server, 0 otherwise */
00077        int uploading;                     /* 1 if an upload is open on the server, 0 otherwise */
00078        time_t last_command_sent;   /* Time the last command was sent to the server */
00079 
00080        char *Buf;                  /* Our buffer for linebuffered read. */
00081        size_t BufSize;
00082        size_t BufUsed;
00083        char *BufPtr;
00084 
00085        void (*network_status_cb)(int state);     /* Callback for update on whether the IPC is locked */
00086        char ip_hostname[256];             /* host name of server to which we are connected (if network) */
00087        char ip_address[64];        /* IP address of server to which we are connected (if network) */
00088 
00089 } CtdlIPC;
00090 
00091 /* C constructor */
00092 CtdlIPC* CtdlIPC_new(int argc, char **argv, char *hostbuf, char *portbuf);
00093 /* C destructor */
00094 void CtdlIPC_delete(CtdlIPC* ipc);
00095 /* Convenience destructor; also nulls out caller's pointer */
00096 void CtdlIPC_delete_ptr(CtdlIPC** pipc);
00097 /* Read a line from server, discarding newline, for chat, will go away */
00098 void CtdlIPC_chat_recv(CtdlIPC* ipc, char *buf);
00099 /* Write a line to server, adding newline, for chat, will go away */
00100 void CtdlIPC_chat_send(CtdlIPC* ipc, const char *buf);
00101 
00102 struct ctdlipcroom {
00103        char RRname[ROOMNAMELEN];   /* Name of room */
00104        long RRunread;                     /* Number of unread messages */
00105        long RRtotal;               /* Total number of messages in room */
00106        char RRinfoupdated;         /* Nonzero if info was updated */
00107        unsigned RRflags;           /* Various flags (see LKRN) */
00108        unsigned RRflags2;          /* Various flags (see LKRN) */
00109        long RRhighest;                    /* Highest message number in room */
00110        long RRlastread;            /* Highest message user has read */
00111        char RRismailbox;           /* Is this room a mailbox room? */
00112        char RRaide;                /* User can do aide commands in room */
00113        long RRnewmail;                    /* Number of new mail messages */
00114        char RRfloor;               /* Which floor this room is on */
00115        char RRcurrentview;         /* The user's current view for this room */
00116        char RRdefaultview;         /* The default view for this room */
00117 };
00118 
00119 
00120 struct parts {
00121        struct parts *next;
00122        char number[16];            /* part number */
00123        char name[PATH_MAX];        /* Name */
00124        char filename[PATH_MAX];    /* Suggested filename */
00125        char mimetype[SIZ];         /* MIME type */
00126        char disposition[SIZ];             /* Content disposition */
00127        unsigned long length;              /* Content length */
00128 };
00129 
00130 
00131 struct ctdlipcmessage {
00132        char msgid[SIZ];            /* Original message ID */
00133        char path[SIZ];                    /* Return path to sender */
00134        char zaps[SIZ];                    /* Message ID that this supersedes */
00135        char subject[SIZ];          /* Message subject */
00136        char email[SIZ];            /* Email address of sender */
00137        char author[SIZ];           /* Sender of message */
00138        char recipient[SIZ];        /* Recipient of message */
00139        char room[SIZ];                    /* Originating room */
00140        char node[SIZ];                    /* Short nodename of origin system */
00141        char hnod[SIZ];                    /* Humannode of origin system */
00142        struct parts *attachments;  /* Available attachments */
00143        char *text;                 /* Message text */
00144        int type;                   /* Message type */
00145        time_t time;                /* Time message was posted */
00146        char nhdr;                  /* Suppress message header? */
00147        char anonymous;                    /* An anonymous message */
00148        char mime_chosen[SIZ];             /* Chosen MIME part to output */
00149        char content_type[SIZ];            /* How would you like that? */
00150        char references[SIZ];              /* Thread references */
00151 };
00152 
00153 
00154 struct ctdlipcfile {
00155        char remote_name[PATH_MAX]; /* Filename on server */
00156        char local_name[PATH_MAX];  /* Filename on client */
00157        char description[80];              /* Description on server */
00158        FILE *local_fd;                    /* Open file on client */
00159        size_t size;                /* Size of file in octets */
00160        unsigned int upload:1;             /* uploading? 0 if downloading */
00161        unsigned int complete:1;    /* Transfer has finished? */
00162 };
00163 
00164 
00165 struct ctdlipcmisc {
00166        long newmail;               /* Number of new Mail messages */
00167        char needregis;                    /* Nonzero if user needs to register */
00168        char needvalid;                    /* Nonzero if users need validation */
00169 };
00170 
00171 enum RoomList {
00172        SubscribedRooms,
00173        SubscribedRoomsWithNewMessages,
00174        SubscribedRoomsWithNoNewMessages,
00175        UnsubscribedRooms,
00176        AllAccessibleRooms,
00177        AllPublicRooms
00178 };
00179 #define AllFloors -1
00180 enum MessageList {
00181        AllMessages,
00182        OldMessages,
00183        NewMessages,
00184        LastMessages,
00185        FirstMessages,
00186        MessagesGreaterThan,
00187        MessagesLessThan
00188 };
00189 enum MessageDirection {
00190        ReadReverse = -1,
00191        ReadForward = 1
00192 };
00193 
00194 /* Shared Diffie-Hellman parameters */
00195 #define DH_P         "F6E33BD70D475906ABCFB368DA2D1E5611D57DFDAC6A10CD78F406D6952519C74E21FFDCC5A780B9359722AACC8036E4CD24D5F5165EAC9EF226DBD9BBCF678F8DDEE86386F1BC20E291A9854A513A2CA326B411DC92E38F2ED2FEB6A3B792F13DB6550371FDBAC5ECA373BE5050CA4905431CA86088737D52B36C8D13CE9CB4EEF4C910285035E8329DD07551A80B87775676DD1067395CCEE9040C9B8BF998C528B3772B4C590A2CF18C5E58929BFCB538A62638B7437A9C68572D15287E97692B0B1EC5444D9DAB6EB062D20B79CA005EC5035065567AFD1FEF9B251D74747C6065D8C8B6B0862D1EE03F3A244C429EADE0CCC5C3A4196F5CBF5AA01A9026EFB20AA90E462BD64620278F271905EB604F38E6CFAE412EAA6C468E3B58170909BC18662FE2053224F30BE4FDB93BF9FBF969D91A5427A0665AC7BD1C43701B991094C92F7A935063055617142164F02973EB4ED86DD74D2BBAB3CD3B28F7BBD8D9F925B0FE92F7F7D0568D783F9ECE7AF96FB5AF274B586924B64639733A73ACA8F2BD1E970DF51ADDD983F7F6361A2B0DC4F086DE26D8656EC8813DE4B74D6D57BC1E690AC2FF1682B7E16938565A41D1DC64C75ADB81DA4582613FC68C0FDD327D35E2CDF20D009465303773EF3870FBDB0985EE7002A95D7912BBCC78187C29DB046763B7FABFF44EABE820F8ED0D7230AA0AF24F428F82448345BC099B"
00196 #define DH_G         "2"
00197 #define DH_L         4096
00198 #define CIT_CIPHERS  "ALL:RC4+RSA:+SSLv2:+TLSv1:!MD5:@STRENGTH"       /* see ciphers(1) */
00199 
00200 int CtdlIPCNoop(CtdlIPC *ipc);
00201 int CtdlIPCEcho(CtdlIPC *ipc, const char *arg, char *cret);
00202 int CtdlIPCQuit(CtdlIPC *ipc);
00203 int CtdlIPCLogout(CtdlIPC *ipc);
00204 int CtdlIPCTryLogin(CtdlIPC *ipc, const char *username, char *cret);
00205 int CtdlIPCTryPassword(CtdlIPC *ipc, const char *passwd, char *cret);
00206 int CtdlIPCTryApopPassword(CtdlIPC *ipc, const char *response, char *cret);
00207 int CtdlIPCCreateUser(CtdlIPC *ipc, const char *username, int selfservice,
00208               char *cret);
00209 int CtdlIPCChangePassword(CtdlIPC *ipc, const char *passwd, char *cret);
00210 int CtdlIPCKnownRooms(CtdlIPC *ipc, enum RoomList which, int floor,
00211               struct march **listing, char *cret);
00212 int CtdlIPCGetConfig(CtdlIPC *ipc, struct ctdluser **uret, char *cret);
00213 int CtdlIPCSetConfig(CtdlIPC *ipc, struct ctdluser *uret, char *cret);
00214 int CtdlIPCGotoRoom(CtdlIPC *ipc, const char *room, const char *passwd,
00215               struct ctdlipcroom **rret, char *cret);
00216 int CtdlIPCGetMessages(CtdlIPC *ipc, enum MessageList which, int whicharg,
00217               const char *mtemplate, unsigned long **mret, char *cret);
00218 int CtdlIPCGetSingleMessage(CtdlIPC *ipc, long msgnum, int headers, int as_mime,
00219               struct ctdlipcmessage **mret, char *cret);
00220 int CtdlIPCWhoKnowsRoom(CtdlIPC *ipc, char **listing, char *cret);
00221 int CtdlIPCServerInfo(CtdlIPC *ipc, char *cret);
00222 /* int CtdlIPCReadDirectory(CtdlIPC *ipc, struct ctdlipcfile **files, char *cret); */
00223 int CtdlIPCReadDirectory(CtdlIPC *ipc, char **listing, char *cret);
00224 int CtdlIPCSetLastRead(CtdlIPC *ipc, long msgnum, char *cret);
00225 int CtdlIPCInviteUserToRoom(CtdlIPC *ipc, const char *username, char *cret);
00226 int CtdlIPCKickoutUserFromRoom(CtdlIPC *ipc, const char *username, char *cret);
00227 int CtdlIPCGetRoomAttributes(CtdlIPC *ipc, struct ctdlroom **qret, char *cret);
00228 int CtdlIPCSetRoomAttributes(CtdlIPC *ipc, int forget, struct ctdlroom *qret,
00229               char *cret);
00230 int CtdlIPCGetRoomAide(CtdlIPC *ipc, char *cret);
00231 int CtdlIPCSetRoomAide(CtdlIPC *ipc, const char *username, char *cret);
00232 int CtdlIPCPostMessage(CtdlIPC *ipc, int flag, int *subject_required, 
00233                                       struct ctdlipcmessage *mr,
00234                                       char *cret);
00235 int CtdlIPCRoomInfo(CtdlIPC *ipc, char **iret, char *cret);
00236 int CtdlIPCDeleteMessage(CtdlIPC *ipc, long msgnum, char *cret);
00237 int CtdlIPCMoveMessage(CtdlIPC *ipc, int copy, long msgnum,
00238               const char *destroom, char *cret);
00239 int CtdlIPCDeleteRoom(CtdlIPC *ipc, int for_real, char *cret);
00240 int CtdlIPCCreateRoom(CtdlIPC *ipc, int for_real, const char *roomname,
00241               int type, const char *password, int floor, char *cret);
00242 int CtdlIPCForgetRoom(CtdlIPC *ipc, char *cret);
00243 int CtdlIPCSystemMessage(CtdlIPC *ipc, const char *message, char **mret,
00244               char *cret);
00245 int CtdlIPCNextUnvalidatedUser(CtdlIPC *ipc, char *cret);
00246 int CtdlIPCGetUserRegistration(CtdlIPC *ipc, const char *username, char **rret,
00247               char *cret);
00248 int CtdlIPCValidateUser(CtdlIPC *ipc, const char *username, int axlevel,
00249               char *cret);
00250 int CtdlIPCSetRoomInfo(CtdlIPC *ipc, int for_real, const char *info,
00251               char *cret);
00252 int CtdlIPCUserListing(CtdlIPC *ipc, char *searchstring, char **list, char *cret);
00253 int CtdlIPCSetRegistration(CtdlIPC *ipc, const char *info, char *cret);
00254 int CtdlIPCMiscCheck(CtdlIPC *ipc, struct ctdlipcmisc *chek, char *cret);
00255 int CtdlIPCDeleteFile(CtdlIPC *ipc, const char *filename, char *cret);
00256 int CtdlIPCMoveFile(CtdlIPC *ipc, const char *filename, const char *destroom,
00257               char *cret);
00258 int CtdlIPCNetSendFile(CtdlIPC *ipc, const char *filename,
00259               const char *destnode, char *cret);
00260 int CtdlIPCOnlineUsers(CtdlIPC *ipc, char **listing, time_t *stamp, char *cret);
00261 int CtdlIPCFileDownload(CtdlIPC *ipc, const char *filename, void **buf,
00262               size_t resume,
00263               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00264               char *cret);
00265 int CtdlIPCAttachmentDownload(CtdlIPC *ipc, long msgnum, const char *part,
00266               void **buf,
00267               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00268               char *cret);
00269 int CtdlIPCImageDownload(CtdlIPC *ipc, const char *filename, void **buf,
00270               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00271               char *cret);
00272 int CtdlIPCFileUpload(CtdlIPC *ipc, const char *save_as, const char *comment,
00273               const char *path, 
00274               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00275               char *cret);
00276 int CtdlIPCImageUpload(CtdlIPC *ipc, int for_real, const char *path,
00277               const char *save_as,
00278               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00279               char *cret);
00280 int CtdlIPCQueryUsername(CtdlIPC *ipc, const char *username, char *cret);
00281 int CtdlIPCFloorListing(CtdlIPC *ipc, char **listing, char *cret);
00282 int CtdlIPCCreateFloor(CtdlIPC *ipc, int for_real, const char *name,
00283               char *cret);
00284 int CtdlIPCDeleteFloor(CtdlIPC *ipc, int for_real, int floornum, char *cret);
00285 int CtdlIPCEditFloor(CtdlIPC *ipc, int floornum, const char *floorname,
00286               char *cret);
00287 int CtdlIPCIdentifySoftware(CtdlIPC *ipc, int developerid, int clientid,
00288               int revision, const char *software_name, const char *hostname,
00289               char *cret);
00290 int CtdlIPCSendInstantMessage(CtdlIPC *ipc, const char *username,
00291               const char *text, char *cret);
00292 int CtdlIPCGetInstantMessage(CtdlIPC *ipc, char **listing, char *cret);
00293 int CtdlIPCEnableInstantMessageReceipt(CtdlIPC *ipc, int mode, char *cret);
00294 int CtdlIPCSetBio(CtdlIPC *ipc, char *bio, char *cret);
00295 int CtdlIPCGetBio(CtdlIPC *ipc, const char *username, char **listing,
00296               char *cret);
00297 int CtdlIPCListUsersWithBios(CtdlIPC *ipc, char **listing, char *cret);
00298 int CtdlIPCStealthMode(CtdlIPC *ipc, int mode, char *cret);
00299 int CtdlIPCTerminateSession(CtdlIPC *ipc, int sid, char *cret);
00300 int CtdlIPCTerminateServerNow(CtdlIPC *ipc, char *cret);
00301 int CtdlIPCTerminateServerScheduled(CtdlIPC *ipc, int mode, char *cret);
00302 int CtdlIPCEnterSystemMessage(CtdlIPC *ipc, const char *filename, const char *text,
00303               char *cret);
00304 int CtdlIPCChangeHostname(CtdlIPC *ipc, const char *hostname, char *cret);
00305 int CtdlIPCChangeRoomname(CtdlIPC *ipc, const char *roomname, char *cret);
00306 int CtdlIPCChangeUsername(CtdlIPC *ipc, const char *username, char *cret);
00307 time_t CtdlIPCServerTime(CtdlIPC *ipc, char *crert);
00308 int CtdlIPCAideGetUserParameters(CtdlIPC *ipc, const char *who,
00309                              struct ctdluser **uret, char *cret);
00310 int CtdlIPCAideSetUserParameters(CtdlIPC *ipc, const struct ctdluser *uret, char *cret);
00311 int CtdlIPCRenameUser(CtdlIPC *ipc, char *oldname, char *newname, char *cret);
00312 int CtdlIPCGetMessageExpirationPolicy(CtdlIPC *ipc, GPEXWhichPolicy which,
00313               struct ExpirePolicy **policy, char *cret);
00314 int CtdlIPCSetMessageExpirationPolicy(CtdlIPC *ipc, int which,
00315               struct ExpirePolicy *policy, char *cret);
00316 int CtdlIPCGetSystemConfig(CtdlIPC *ipc, char **listing, char *cret);
00317 int CtdlIPCSetSystemConfig(CtdlIPC *ipc, const char *listing, char *cret);
00318 int CtdlIPCGetSystemConfigByType(CtdlIPC *ipc, const char *mimetype,
00319                      char **listing, char *cret);
00320 int CtdlIPCSetSystemConfigByType(CtdlIPC *ipc, const char *mimetype,
00321               const char *listing, char *cret);
00322 int CtdlIPCGetRoomNetworkConfig(CtdlIPC *ipc, char **listing, char *cret);
00323 int CtdlIPCSetRoomNetworkConfig(CtdlIPC *ipc, const char *listing, char *cret);
00324 int CtdlIPCRequestClientLogout(CtdlIPC *ipc, int session, char *cret);
00325 int CtdlIPCSetMessageSeen(CtdlIPC *ipc, long msgnum, int seen, char *cret);
00326 int CtdlIPCStartEncryption(CtdlIPC *ipc, char *cret);
00327 int CtdlIPCDirectoryLookup(CtdlIPC *ipc, const char *address, char *cret);
00328 int CtdlIPCSpecifyPreferredFormats(CtdlIPC *ipc, char *cret, char *formats);
00329 int CtdlIPCInternalProgram(CtdlIPC *ipc, int secret, char *cret);
00330 
00331 /* ************************************************************************** */
00332 /*             Stuff below this line is not for public consumption            */
00333 /* ************************************************************************** */
00334 
00335 char *CtdlIPCReadListing(CtdlIPC *ipc, char *dest);
00336 int CtdlIPCSendListing(CtdlIPC *ipc, const char *listing);
00337 size_t CtdlIPCPartialRead(CtdlIPC *ipc, void **buf, size_t offset,
00338               size_t bytes, char *cret);
00339 int CtdlIPCEndUpload(CtdlIPC *ipc, int discard, char *cret);
00340 int CtdlIPCWriteUpload(CtdlIPC *ipc, FILE *uploadFP,
00341               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00342               char *cret);
00343 int CtdlIPCEndDownload(CtdlIPC *ipc, char *cret);
00344 int CtdlIPCReadDownload(CtdlIPC *ipc, void **buf, size_t bytes, size_t resume,
00345               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00346               char *cret);
00347 int CtdlIPCHighSpeedReadDownload(CtdlIPC *ipc, void **buf, size_t bytes,
00348               size_t resume,
00349               void (*progress_gauge_callback)(CtdlIPC*, unsigned long, unsigned long),
00350               char *cret);
00351 int CtdlIPCGenericCommand(CtdlIPC *ipc, const char *command,
00352               const char *to_send, size_t bytes_to_send, char **to_receive,
00353               size_t *bytes_to_receive, char *proto_response);
00354 
00355 /* Internals */
00356 int starttls(CtdlIPC *ipc);
00357 void setCryptoStatusHook(void (*hook)(char *s));
00358 void CtdlIPC_SetNetworkStatusCallback(CtdlIPC *ipc, void (*hook)(int state));
00359 /* This is all Ford's doing.  FIXME: figure out what it's doing */
00360 extern int (*error_printf)(char *s, ...);
00361 void setIPCDeathHook(void (*hook)(void));
00362 void setIPCErrorPrintf(int (*func)(char *s, ...));
00363 void connection_died(CtdlIPC* ipc, int using_ssl);
00364 int CtdlIPC_getsockfd(CtdlIPC* ipc);
00365 char CtdlIPC_get(CtdlIPC* ipc);
00366 
00367 
00368 
00369 static INLINE void CtdlIPC_lock(CtdlIPC *ipc)
00370 {
00371        if (ipc->network_status_cb) ipc->network_status_cb(1);
00372 #ifdef THREADED_CLIENT
00373        pthread_mutex_lock(&(ipc->mutex));
00374 #endif
00375 }
00376 
00377 
00378 static INLINE void CtdlIPC_unlock(CtdlIPC *ipc)
00379 {
00380 #ifdef THREADED_CLIENT
00381        pthread_mutex_unlock(&(ipc->mutex));
00382 #endif
00383        if (ipc->network_status_cb) ipc->network_status_cb(0);
00384 }
00385 
00386 #ifdef __cplusplus
00387 }
00388 #endif