Back to index

citadel  8.12
Classes | Defines | Enumerations | Functions
ctdl_module.h File Reference
#include "sysdep.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <signal.h>
#include <pwd.h>
#include <errno.h>
#include <syslog.h>
#include <sys/types.h>
#include <time.h>
#include <sys/wait.h>
#include <string.h>
#include <limits.h>
#include "snprintf.h"
#include <libcitadel.h>
#include "server.h"
#include "sysdep_decls.h"
#include "msgbase.h"
#include "threads.h"
#include "citadel_dirs.h"
#include "context.h"

Go to the source code of this file.

Classes

struct  config

Defines

#define GC_MALLOC   malloc
#define GC_MALLOC_ATOMIC   malloc
#define GC_FREE   free
#define GC_REALLOC   realloc
#define CTDL_MODULE_INIT(module_name)   char *ctdl_module_##module_name##_init (int threading)
#define CTDL_INIT_CALL(module_name)   ctdl_module_##module_name##_init (threading)
#define CTDL_MODULE_UPGRADE(module_name)   char *ctdl_module_##module_name##_upgrade (void)
#define CTDL_UPGRADE_CALL(module_name)   ctdl_module_##module_name##_upgrade ()
#define CtdlAideMessage(TEXT, SUBJECT)   quickie_message("Citadel",NULL,NULL,AIDEROOM,TEXT,FMT_CITADEL,SUBJECT)
#define PRIO_QUEUE   500
#define PRIO_AGGR   1000
#define PRIO_SEND   1500
#define PRIO_CLEANUP   2000
#define PRIO_HOUSE   3000
#define PRIO_CREATE   10000
#define PRIO_LOGOUT   15000
#define PRIO_LOGIN   20000
#define PRIO_START   25000
#define PRIO_STOP   30000
#define PRIO_ASYNC   35000
#define PRIO_SHUTDOWN   40000
#define PRIO_UNSTEALTH   45000
#define PRIO_STEALTH   50000
#define DIRECTORY_USER_DEL   1
#define DIRECTORY_CREATE_HOST   2
#define DIRECTORY_CREATE_OBJECT   3
#define DIRECTORY_ATTRIB_ADD   4
#define DIRECTORY_SAVE_OBJECT   5
#define DIRECTORY_FREE_OBJECT   6

Enumerations

enum  {
  crr_ok, crr_room_not_found, crr_already_exists, crr_noneditable,
  crr_invalid_floor, crr_access_denied
}
enum  {
  ac_none, ac_logged_in_or_guest, ac_logged_in, ac_room_aide,
  ac_aide, ac_internal
}
enum  {
  pass_ok, pass_already_logged_in, pass_no_user, pass_internal_error,
  pass_wrong_password
}
enum  { login_ok, login_already_logged_in, login_too_many_users, login_not_found }

Functions

void CtdlRegisterSessionHook (void(*fcn_ptr)(void), int EventType, int Priority)
void CtdlUnregisterSessionHook (void(*fcn_ptr)(void), int EventType)
void CtdlShutdownServiceHooks (void)
void CtdlRegisterUserHook (void(*fcn_ptr)(struct ctdluser *), int EventType)
void CtdlUnregisterUserHook (void(*fcn_ptr)(struct ctdluser *), int EventType)
void CtdlRegisterXmsgHook (int(*fcn_ptr)(char *, char *, char *, char *), int order)
void CtdlUnregisterXmsgHook (int(*fcn_ptr)(char *, char *, char *, char *), int order)
void CtdlRegisterMessageHook (int(*handler)(struct CtdlMessage *), int EventType)
void CtdlUnregisterMessageHook (int(*handler)(struct CtdlMessage *), int EventType)
void CtdlRegisterNetprocHook (int(*handler)(struct CtdlMessage *, char *))
void CtdlUnregisterNetprocHook (int(*handler)(struct CtdlMessage *, char *))
void CtdlRegisterRoomHook (int(*fcn_ptr)(struct ctdlroom *))
void CtdlUnregisterRoomHook (int(*fnc_ptr)(struct ctdlroom *))
void CtdlRegisterDeleteHook (void(*handler)(char *, long))
void CtdlUnregisterDeleteHook (void(*handler)(char *, long))
void CtdlRegisterCleanupHook (void(*fcn_ptr)(void))
void CtdlUnregisterCleanupHook (void(*fcn_ptr)(void))
void CtdlRegisterEVCleanupHook (void(*fcn_ptr)(void))
void CtdlUnregisterEVCleanupHook (void(*fcn_ptr)(void))
void CtdlRegisterProtoHook (void(*handler)(char *), char *cmd, char *desc)
void CtdlRegisterServiceHook (int tcp_port, char *sockpath, void(*h_greeting_function)(void), void(*h_command_function)(void), void(*h_async_function)(void), const char *ServiceName)
void CtdlUnregisterServiceHook (int tcp_port, char *sockpath, void(*h_greeting_function)(void), void(*h_command_function)(void), void(*h_async_function)(void))
void CtdlRegisterFixedOutputHook (char *content_type, void(*output_function)(char *supplied_data, int len))
void CtdlUnRegisterFixedOutputHook (char *content_type)
void CtdlRegisterMaintenanceThread (char *name, void *(*thread_proc)(void *arg))
void CtdlRegisterSearchFuncHook (void(*fcn_ptr)(int *, long **, const char *), char *name)
int CtdlRegisterDirectoryServiceFunc (int(*func)(char *cn, char *ou, void **object), int cmd, char *module)
int CtdlDoDirectoryServiceFunc (char *cn, char *ou, void **object, char *module, int cmd)
void CtdlModuleStartCryptoMsgs (char *ok_response, char *nosup_response, char *error_response)
struct CitContextCtdlGetContextArray (int *count)
void CtdlFillSystemContext (struct CitContext *context, char *name)
int CtdlTrySingleUser (void)
void CtdlEndSingleUser (void)
int CtdlWantSingleUser (void)
int CtdlIsSingleUser (void)
int CtdlIsUserLoggedIn (char *user_name)
int CtdlIsUserLoggedInByNum (long usernum)
void CtdlBumpNewMailCounter (long which_user)
long CtdlGetCurrentMessageNumber (void)
unsigned CtdlCreateRoom (char *new_room_name, int new_room_type, char *new_room_pass, int new_room_floor, int really_create, int avoid_access, int new_room_view)
int CtdlGetRoom (struct ctdlroom *qrbuf, char *room_name)
int CtdlGetRoomLock (struct ctdlroom *qrbuf, char *room_name)
int CtdlDoIHavePermissionToDeleteThisRoom (struct ctdlroom *qr)
void CtdlRoomAccess (struct ctdlroom *roombuf, struct ctdluser *userbuf, int *result, int *view)
void CtdlPutRoomLock (struct ctdlroom *qrbuf)
void CtdlForEachRoom (void(*CallBack)(struct ctdlroom *EachRoom, void *out_data), void *in_data)
void CtdlDeleteRoom (struct ctdlroom *qrbuf)
int CtdlRenameRoom (char *old_name, char *new_name, int new_floor)
void CtdlUserGoto (char *where, int display_result, int transiently, int *msgs, int *new)
struct floorCtdlGetCachedFloor (int floor_num)
void CtdlScheduleRoomForDeletion (struct ctdlroom *qrbuf)
void CtdlGetFloor (struct floor *flbuf, int floor_num)
void CtdlPutFloor (struct floor *flbuf, int floor_num)
void CtdlPutFloorLock (struct floor *flbuf, int floor_num)
int CtdlGetFloorByName (const char *floor_name)
int CtdlGetFloorByNameLock (const char *floor_name)
int CtdlGetAvailableFloor (void)
int CtdlIsNonEditable (struct ctdlroom *qrbuf)
void CtdlPutRoom (struct ctdlroom *)
int CtdlAccessCheck (int)
void CtdlModuleDoSearch (int *num_msgs, long **search_msgs, const char *search_string, const char *func_name)
int CtdlGetUser (struct ctdluser *usbuf, char *name)
int CtdlGetUserLen (struct ctdluser *usbuf, const char *name, long len)
int CtdlGetUserLock (struct ctdluser *usbuf, char *name)
void CtdlPutUser (struct ctdluser *usbuf)
void CtdlPutUserLock (struct ctdluser *usbuf)
int CtdlGetUserByNumber (struct ctdluser *usbuf, long number)
void CtdlGetRelationship (visit *vbuf, struct ctdluser *rel_user, struct ctdlroom *rel_room)
void CtdlSetRelationship (visit *newvisit, struct ctdluser *rel_user, struct ctdlroom *rel_room)
void CtdlMailboxName (char *buf, size_t n, const struct ctdluser *who, const char *prefix)
int CtdlLoginExistingUser (char *authname, const char *username)
int CtdlTryPassword (const char *password, long len)
void CtdlUserLogout (void)
char * CtdlGetSysConfig (char *sysconfname)
void CtdlPutSysConfig (char *sysconfname, char *sysconfdata)
long CtdlLocateMessageByEuid (char *euid, struct ctdlroom *qrbuf)

Class Documentation

struct config

Definition at line 283 of file ctdl_module.h.

Class Members
int c_aide_zap
char c_aideroom
char c_allow_spoofing
int c_auth_mode
char c_auto_cull
char c_baseroom
char c_creataide
char c_createax
uid_t c_ctdluid
char c_default_cal_zone
char c_disable_newu
char c_enable_fulltext
char c_fqdn
char c_funambol_auth
char c_funambol_host
int c_funambol_port
char c_funambol_source
int c_guest_logins
char c_humannode
char c_imap_keep_from
int c_imap_port
int c_imaps_port
char c_initax
char c_instant_expunge
char c_ip_addr
char c_journal_dest
char c_journal_email
char c_journal_pubmsgs
char c_ldap_base_dn
char c_ldap_bind_dn
char c_ldap_bind_pw
char c_ldap_host
int c_ldap_port
char c_logpages
int c_managesieve_port
char c_master_pass
char c_master_user
int c_max_workers
long c_maxmsglen
int c_maxsessions
int c_min_workers
char c_moreprompt
int c_msa_port
time_t c_net_freq
long c_niu_1
char c_niu_2
int c_niu_3
int c_niu_4
char c_nodename
char c_pager_program
int c_pftcpdict_port
char c_phonenum
time_t c_pop3_fastest
time_t c_pop3_fetch
int c_pop3_port
int c_pop3s_port
int c_port_number
int c_purge_hour
char c_rbl_at_greeting
char c_regiscall
char c_restrict
int c_rfc822_strict_from
int c_roompurge
char c_site_location
int c_sleeping
int c_smtp_port
int c_smtps_port
int c_spam_flag_only
char c_sysadm
char c_twitdetect
char c_twitroom
int c_userpurge
int c_xmpp_c2s_port
int c_xmpp_s2s_port

Define Documentation

#define CTDL_INIT_CALL (   module_name)    ctdl_module_##module_name##_init (threading)

Definition at line 69 of file ctdl_module.h.

#define CTDL_MODULE_INIT (   module_name)    char *ctdl_module_##module_name##_init (int threading)

Definition at line 67 of file ctdl_module.h.

#define CTDL_MODULE_UPGRADE (   module_name)    char *ctdl_module_##module_name##_upgrade (void)

Definition at line 71 of file ctdl_module.h.

#define CTDL_UPGRADE_CALL (   module_name)    ctdl_module_##module_name##_upgrade ()

Definition at line 73 of file ctdl_module.h.

#define CtdlAideMessage (   TEXT,
  SUBJECT 
)    quickie_message("Citadel",NULL,NULL,AIDEROOM,TEXT,FMT_CITADEL,SUBJECT)

Definition at line 75 of file ctdl_module.h.

#define DIRECTORY_ATTRIB_ADD   4

Definition at line 167 of file ctdl_module.h.

#define DIRECTORY_CREATE_HOST   2

Definition at line 165 of file ctdl_module.h.

#define DIRECTORY_CREATE_OBJECT   3

Definition at line 166 of file ctdl_module.h.

#define DIRECTORY_FREE_OBJECT   6

Definition at line 169 of file ctdl_module.h.

#define DIRECTORY_SAVE_OBJECT   5

Definition at line 168 of file ctdl_module.h.

#define DIRECTORY_USER_DEL   1

Definition at line 164 of file ctdl_module.h.

#define GC_FREE   free

Definition at line 14 of file ctdl_module.h.

#define GC_MALLOC   malloc

Definition at line 12 of file ctdl_module.h.

#define GC_MALLOC_ATOMIC   malloc

Definition at line 13 of file ctdl_module.h.

#define GC_REALLOC   realloc

Definition at line 15 of file ctdl_module.h.

#define PRIO_AGGR   1000

Definition at line 81 of file ctdl_module.h.

#define PRIO_ASYNC   35000

Definition at line 97 of file ctdl_module.h.

#define PRIO_CLEANUP   2000

Definition at line 83 of file ctdl_module.h.

#define PRIO_CREATE   10000

Definition at line 87 of file ctdl_module.h.

#define PRIO_HOUSE   3000

Definition at line 85 of file ctdl_module.h.

#define PRIO_LOGIN   20000

Definition at line 91 of file ctdl_module.h.

#define PRIO_LOGOUT   15000

Definition at line 89 of file ctdl_module.h.

#define PRIO_QUEUE   500

Definition at line 80 of file ctdl_module.h.

#define PRIO_SEND   1500

Definition at line 82 of file ctdl_module.h.

#define PRIO_SHUTDOWN   40000

Definition at line 99 of file ctdl_module.h.

#define PRIO_START   25000

Definition at line 93 of file ctdl_module.h.

#define PRIO_STEALTH   50000

Definition at line 103 of file ctdl_module.h.

#define PRIO_STOP   30000

Definition at line 95 of file ctdl_module.h.

#define PRIO_UNSTEALTH   45000

Definition at line 101 of file ctdl_module.h.


Enumeration Type Documentation

anonymous enum
Enumerator:
crr_ok 
crr_room_not_found 
crr_already_exists 
crr_noneditable 
crr_invalid_floor 
crr_access_denied 

Definition at line 247 of file ctdl_module.h.

     {
       crr_ok,                            /* success */
       crr_room_not_found,         /* room not found */
       crr_already_exists,         /* new name already exists */
       crr_noneditable,            /* cannot edit this room */
       crr_invalid_floor,          /* target floor does not exist */
       crr_access_denied           /* not allowed to edit this room */
};
anonymous enum
Enumerator:
ac_none 
ac_logged_in_or_guest 
ac_logged_in 
ac_room_aide 
ac_aide 
ac_internal 

Definition at line 264 of file ctdl_module.h.

anonymous enum
Enumerator:
pass_ok 
pass_already_logged_in 
pass_no_user 
pass_internal_error 
pass_wrong_password 

Definition at line 388 of file ctdl_module.h.

anonymous enum
Enumerator:
login_ok 
login_already_logged_in 
login_too_many_users 
login_not_found 

Definition at line 400 of file ctdl_module.h.


Function Documentation

int CtdlAccessCheck ( int  )

Definition at line 672 of file citserver.c.

                                        {

       if (CC->internal_pgm) return(0);
       if (required_level >= ac_internal) {
              cprintf("%d This is not a user-level command.\n",
                     ERROR + HIGHER_ACCESS_REQUIRED);
              return(-1);
       }

       if ((required_level >= ac_logged_in_or_guest) && (CC->logged_in == 0) && (!config.c_guest_logins)) {
              cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
              return(-1);
       }

       if ((required_level >= ac_logged_in) && (CC->logged_in == 0)) {
              cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
              return(-1);
       }

       if (CC->user.axlevel >= AxAideU) return(0);
       if (required_level >= ac_aide) {
              cprintf("%d This command requires Aide access.\n",
                     ERROR + HIGHER_ACCESS_REQUIRED);
              return(-1);
       }

       if (is_room_aide()) return(0);
       if (required_level >= ac_room_aide) {
              cprintf("%d This command requires Aide or Room Aide access.\n",
                     ERROR + HIGHER_ACCESS_REQUIRED);
              return(-1);
       }

       /* shhh ... succeed quietly */
       return(0);
}

Here is the call graph for this function:

void CtdlBumpNewMailCounter ( long  which_user)

Definition at line 190 of file context.c.

{
       CitContext *ptr;

       begin_critical_section(S_SESSION_TABLE);

       for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
              if (ptr->user.usernum == which_user) {
                     ptr->newmail += 1;
              }
       }

       end_critical_section(S_SESSION_TABLE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned CtdlCreateRoom ( char *  new_room_name,
int  new_room_type,
char *  new_room_pass,
int  new_room_floor,
int  really_create,
int  avoid_access,
int  new_room_view 
)

Definition at line 1876 of file room_ops.c.

{

       struct ctdlroom qrbuf;
       struct floor flbuf;
       visit vbuf;

       syslog(LOG_DEBUG, "CtdlCreateRoom(name=%s, type=%d, view=%d)\n",
              new_room_name, new_room_type, new_room_view);

       if (CtdlGetRoom(&qrbuf, new_room_name) == 0) {
              syslog(LOG_DEBUG, "%s already exists.\n", new_room_name);
              return(0);
       }

       memset(&qrbuf, 0, sizeof(struct ctdlroom));
       safestrncpy(qrbuf.QRpasswd, new_room_pass, sizeof qrbuf.QRpasswd);
       qrbuf.QRflags = QR_INUSE;
       if (new_room_type > 0)
              qrbuf.QRflags = (qrbuf.QRflags | QR_PRIVATE);
       if (new_room_type == 1)
              qrbuf.QRflags = (qrbuf.QRflags | QR_GUESSNAME);
       if (new_room_type == 2)
              qrbuf.QRflags = (qrbuf.QRflags | QR_PASSWORDED);
       if ( (new_room_type == 4) || (new_room_type == 5) ) {
              qrbuf.QRflags = (qrbuf.QRflags | QR_MAILBOX);
              /* qrbuf.QRflags2 |= QR2_SUBJECTREQ; */
       }

       /* If the user is requesting a personal room, set up the room
        * name accordingly (prepend the user number)
        */
       if (new_room_type == 4) {
              CtdlMailboxName(qrbuf.QRname, sizeof qrbuf.QRname, &CC->user, new_room_name);
       }
       else {
              safestrncpy(qrbuf.QRname, new_room_name, sizeof qrbuf.QRname);
       }

       /* If the room is private, and the system administrator has elected
        * to automatically grant room aide privileges, do so now.
        */
       if ((qrbuf.QRflags & QR_PRIVATE) && (CREATAIDE == 1)) {
              qrbuf.QRroomaide = CC->user.usernum;
       }
       /* Blog owners automatically become room aides of their blogs.
        * (In the future we will offer a site-wide configuration setting to suppress this behavior.)
        */
       else if (new_room_view == VIEW_BLOG) {
              qrbuf.QRroomaide = CC->user.usernum;
       }
       /* Otherwise, set the room aide to undefined.
        */
       else {
              qrbuf.QRroomaide = (-1L);
       }

       /* 
        * If the caller is only interested in testing whether this will work,
        * return now without creating the room.
        */
       if (!really_create) return (qrbuf.QRflags);

       qrbuf.QRnumber = get_new_room_number();
       qrbuf.QRhighest = 0L;       /* No messages in this room yet */
       time(&qrbuf.QRgen);  /* Use a timestamp as the generation number */
       qrbuf.QRfloor = new_room_floor;
       qrbuf.QRdefaultview = new_room_view;

       /* save what we just did... */
       CtdlPutRoom(&qrbuf);

       /* bump the reference count on whatever floor the room is on */
       lgetfloor(&flbuf, (int) qrbuf.QRfloor);
       flbuf.f_ref_count = flbuf.f_ref_count + 1;
       lputfloor(&flbuf, (int) qrbuf.QRfloor);

       /* Grant the creator access to the room unless the avoid_access
        * parameter was specified.
        */
       if ( (CC->logged_in) && (avoid_access == 0) ) {
              CtdlGetRelationship(&vbuf, &CC->user, &qrbuf);
              vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
              vbuf.v_flags = vbuf.v_flags | V_ACCESS;
              CtdlSetRelationship(&vbuf, &CC->user, &qrbuf);
       }

       /* resume our happy day */
       return (qrbuf.QRflags);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlDeleteRoom ( struct ctdlroom qrbuf)

Definition at line 1750 of file room_ops.c.

{
       struct floor flbuf;
       char filename[100];
       /* TODO: filename magic? does this realy work? */

       syslog(LOG_NOTICE, "Deleting room <%s>\n", qrbuf->QRname);

       /* Delete the info file */
       assoc_file_name(filename, sizeof filename, qrbuf, ctdl_info_dir);
       unlink(filename);

       /* Delete the image file */
       assoc_file_name(filename, sizeof filename, qrbuf, ctdl_image_dir);
       unlink(filename);

       /* Delete the room's network config file */
       assoc_file_name(filename, sizeof filename, qrbuf, ctdl_netcfg_dir);
       unlink(filename);

       /* Delete the messages in the room
        * (Careful: this opens an S_ROOMS critical section!)
        */
       CtdlDeleteMessages(qrbuf->QRname, NULL, 0, "");

       /* Flag the room record as not in use */
       CtdlGetRoomLock(qrbuf, qrbuf->QRname);
       qrbuf->QRflags = 0;
       CtdlPutRoomLock(qrbuf);

       /* then decrement the reference count for the floor */
       lgetfloor(&flbuf, (int) (qrbuf->QRfloor));
       flbuf.f_ref_count = flbuf.f_ref_count - 1;
       lputfloor(&flbuf, (int) (qrbuf->QRfloor));

       /* Delete the room record from the database! */
       b_deleteroom(qrbuf->QRname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlDoDirectoryServiceFunc ( char *  cn,
char *  ou,
void **  object,
char *  module,
int  cmd 
)

Definition at line 1794 of file room_ops.c.

                                                               {

       if ((!(CC->logged_in)) && (!(CC->internal_pgm))) {
              return(0);
       }

       if (CtdlIsNonEditable(qr)) {
              return(0);
       }

       /*
        * For mailboxes, check stuff
        */
       if (qr->QRflags & QR_MAILBOX) {

              if (strlen(qr->QRname) < 12) return(0); /* bad name */

              if (atol(qr->QRname) != CC->user.usernum) {
                     return(0);    /* not my room */
              }

              /* Can't delete your Mail> room */
              if (!strcasecmp(&qr->QRname[11], MAILROOM)) return(0);

              /* Otherwise it's ok */
              return(1);
       }

       /*
        * For normal rooms, just check for aide or room aide status.
        */
       return(is_room_aide());
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlEndSingleUser ( void  )

Definition at line 119 of file context.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlFillSystemContext ( struct CitContext context,
char *  name 
)

Definition at line 530 of file context.c.

{
       char sysname[SIZ];
       long len;

       memset(context, 0, sizeof(CitContext));
       context->internal_pgm = 1;
       context->cs_pid = 0;
       strcpy (sysname, "SYS_");
       strcat (sysname, name);
       len = cutuserkey(sysname);
       memcpy(context->curr_user, sysname, len + 1);
       context->client_socket = (-1);
       context->state = CON_SYS;
       context->ServiceName = name;

       /* internal_create_user has the side effect of loading the user regardless of wether they
        * already existed or needed to be created
        */
       internal_create_user (sysname, len, &(context->user), -1) ;
       
       /* Check to see if the system user needs upgrading */
       if (context->user.usernum == 0)
       {      /* old system user with number 0, upgrade it */
              context->user.usernum = get_new_user_number();
              CON_syslog(LOG_INFO, "Upgrading system user \"%s\" from user number 0 to user number %ld\n", context->user.fullname, context->user.usernum);
              /* add user to the database */
              CtdlPutUser(&(context->user));
              cdb_store(CDB_USERSBYNUMBER, &(context->user.usernum), sizeof(long), context->user.fullname, strlen(context->user.fullname)+1);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlForEachRoom ( void(*)(struct ctdlroom *EachRoom, void *out_data)  CallBack,
void *  in_data 
)

Definition at line 582 of file room_ops.c.

{
       struct ctdlroom qrbuf;
       struct cdbdata *cdbqr;

       cdb_rewind(CDB_ROOMS);

       while (cdbqr = cdb_next_item(CDB_ROOMS), cdbqr != NULL) {
              memset(&qrbuf, 0, sizeof(struct ctdlroom));
              memcpy(&qrbuf, cdbqr->ptr,
                     ((cdbqr->len > sizeof(struct ctdlroom)) ?
                     sizeof(struct ctdlroom) : cdbqr->len));
              cdb_free(cdbqr);
              room_sanity_check(&qrbuf);
              if (qrbuf.QRflags & QR_INUSE)
                     (*CallBack)(&qrbuf, in_data);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetAvailableFloor ( void  )

Definition at line 445 of file room_ops.c.

{
       int a;
       struct floor *flbuf = NULL;

       for (a = 0; a < MAXFLOORS; a++) {
              flbuf = CtdlGetCachedFloor(a);

              /* check to see if it already exists */
              if ((flbuf->f_flags & F_INUSE) == 0) {
                     return a;
              }
       }
       return -1;
}

Here is the call graph for this function:

struct floor* CtdlGetCachedFloor ( int  floor_num) [read]

Definition at line 503 of file room_ops.c.

                                                {
       static int initialized = 0;
       int i;
       int fetch_new = 0;
       struct floor *fl = NULL;

       begin_critical_section(S_FLOORCACHE);
       if (initialized == 0) {
              for (i=0; i<MAXFLOORS; ++i) {
                     floorcache[floor_num] = NULL;
              }
       initialized = 1;
       }
       if (floorcache[floor_num] == NULL) {
              fetch_new = 1;
       }
       end_critical_section(S_FLOORCACHE);

       if (fetch_new) {
              fl = malloc(sizeof(struct floor));
              CtdlGetFloor(fl, floor_num);
              begin_critical_section(S_FLOORCACHE);
              if (floorcache[floor_num] != NULL) {
                     free(floorcache[floor_num]);
              }
              floorcache[floor_num] = fl;
              end_critical_section(S_FLOORCACHE);
       }

       return(floorcache[floor_num]);
}

Here is the call graph for this function:

Here is the caller graph for this function:

struct CitContext* CtdlGetContextArray ( int *  count) [read]

Definition at line 503 of file context.c.

{
       int nContexts, i;
       CitContext *nptr, *cptr;
       
       nContexts = num_sessions;
       nptr = malloc(sizeof(CitContext) * nContexts);
       if (!nptr) {
              *count = 0;
              return NULL;
       }
       begin_critical_section(S_SESSION_TABLE);
       for (cptr = ContextList, i=0; cptr != NULL && i < nContexts; cptr = cptr->next, i++) {
              memcpy(&nptr[i], cptr, sizeof (CitContext));
       }
       end_critical_section (S_SESSION_TABLE);
       
       *count = i;
       return nptr;
}

Here is the call graph for this function:

Here is the caller graph for this function:

long CtdlGetCurrentMessageNumber ( void  )

Definition at line 285 of file control.c.

{
       long retval = 0L;
       begin_critical_section(S_CONTROL);
       get_control();
       retval = CitControl.MMhighest;
       end_critical_section(S_CONTROL);
       return(retval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlGetFloor ( struct floor flbuf,
int  floor_num 
)

Definition at line 465 of file room_ops.c.

{
       struct cdbdata *cdbfl;

       memset(flbuf, 0, sizeof(struct floor));
       cdbfl = cdb_fetch(CDB_FLOORTAB, &floor_num, sizeof(int));
       if (cdbfl != NULL) {
              memcpy(flbuf, cdbfl->ptr,
                     ((cdbfl->len > sizeof(struct floor)) ?
                     sizeof(struct floor) : cdbfl->len));
              cdb_free(cdbfl);
       } else {
              if (floor_num == 0) {
                     safestrncpy(flbuf->f_name, "Main Floor", 
                            sizeof flbuf->f_name);
                     flbuf->f_flags = F_INUSE;
                     flbuf->f_ref_count = 3;
              }
       }

}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetFloorByName ( const char *  floor_name)

Definition at line 411 of file room_ops.c.

{
       int a;
       struct floor *flbuf = NULL;

       for (a = 0; a < MAXFLOORS; ++a) {
              flbuf = CtdlGetCachedFloor(a);

              /* check to see if it already exists */
              if ((!strcasecmp(flbuf->f_name, floor_name))
                  && (flbuf->f_flags & F_INUSE)) {
                     return a;
              }
       }
       return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetFloorByNameLock ( const char *  floor_name)

Definition at line 433 of file room_ops.c.

Here is the call graph for this function:

void CtdlGetRelationship ( visit vbuf,
struct ctdluser rel_user,
struct ctdlroom rel_room 
)

Definition at line 326 of file user_ops.c.

{

       char IndexBuf[32];
       int IndexLen;
       struct cdbdata *cdbvisit;

       /* Generate an index */
       IndexLen = GenerateRelationshipIndex(IndexBuf,
                                        rel_room->QRnumber,
                                        rel_room->QRgen,
                                        rel_user->usernum);

       /* Clear out the buffer */
       memset(vbuf, 0, sizeof(visit));

       cdbvisit = cdb_fetch(CDB_VISIT, IndexBuf, IndexLen);
       if (cdbvisit != NULL) {
              memcpy(vbuf, cdbvisit->ptr,
                     ((cdbvisit->len > sizeof(visit)) ?
                     sizeof(visit) : cdbvisit->len));
              cdb_free(cdbvisit);
       }
       else {
              /* If this is the first time the user has seen this room,
               * set the view to be the default for the room.
               */
              vbuf->v_view = rel_room->QRdefaultview;
       }

       /* Set v_seen if necessary */
       if (vbuf->v_seen[0] == 0) {
              snprintf(vbuf->v_seen, sizeof vbuf->v_seen, "*:%ld", vbuf->v_lastseen);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetRoom ( struct ctdlroom qrbuf,
char *  room_name 
)

Definition at line 286 of file room_ops.c.

{
       struct cdbdata *cdbqr;
       char lowercase_name[ROOMNAMELEN];
       char personal_lowercase_name[ROOMNAMELEN];
       char *dptr, *sptr, *eptr;

       dptr = lowercase_name;
       sptr = room_name;
       eptr = (dptr + (sizeof lowercase_name - 1));
       while (!IsEmptyStr(sptr) && (dptr < eptr)){
              *dptr = tolower(*sptr);
              sptr++; dptr++;
       }
       *dptr = '\0';

       memset(qrbuf, 0, sizeof(struct ctdlroom));

       /* First, try the public namespace */
       cdbqr = cdb_fetch(CDB_ROOMS,
                       lowercase_name, strlen(lowercase_name));

       /* If that didn't work, try the user's personal namespace */
       if (cdbqr == NULL) {
              snprintf(personal_lowercase_name,
                      sizeof personal_lowercase_name, "%010ld.%s",
                      CC->user.usernum, lowercase_name);
              cdbqr = cdb_fetch(CDB_ROOMS,
                              personal_lowercase_name,
                              strlen(personal_lowercase_name));
       }
       if (cdbqr != NULL) {
              memcpy(qrbuf, cdbqr->ptr,
                     ((cdbqr->len > sizeof(struct ctdlroom)) ?
                     sizeof(struct ctdlroom) : cdbqr->len));
              cdb_free(cdbqr);

              room_sanity_check(qrbuf);

              return (0);
       } else {
              return (1);
       }
}

Here is the call graph for this function:

int CtdlGetRoomLock ( struct ctdlroom qrbuf,
char *  room_name 
)

Definition at line 334 of file room_ops.c.

{
       register int retval;
       retval = CtdlGetRoom(qrbuf, room_name);
       if (retval == 0) begin_critical_section(S_ROOMS);
       return(retval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* CtdlGetSysConfig ( char *  sysconfname)

Definition at line 5328 of file msgbase.c.

                                          {
       char hold_rm[ROOMNAMELEN];
       long msgnum;
       char *conf;
       struct CtdlMessage *msg;
       char buf[SIZ];
       
       strcpy(hold_rm, CC->room.QRname);
       if (CtdlGetRoom(&CC->room, SYSCONFIGROOM) != 0) {
              CtdlGetRoom(&CC->room, hold_rm);
              return NULL;
       }


       /* We want the last (and probably only) config in this room */
       begin_critical_section(S_CONFIG);
       config_msgnum = (-1L);
       CtdlForEachMessage(MSGS_LAST, 1, NULL, sysconfname, NULL,
                        CtdlGetSysConfigBackend, NULL);
       msgnum = config_msgnum;
       end_critical_section(S_CONFIG);

       if (msgnum < 0L) {
              conf = NULL;
       }
       else {
              msg = CtdlFetchMessage(msgnum, 1);
              if (msg != NULL) {
                     conf = strdup(msg->cm_fields['M']);
                     CtdlFreeMessage(msg);
              }
              else {
                     conf = NULL;
              }
       }

       CtdlGetRoom(&CC->room, hold_rm);

       if (conf != NULL) do {
                     extract_token(buf, conf, 0, '\n', sizeof buf);
                     strcpy(conf, &conf[strlen(buf)+1]);
              } while ( (!IsEmptyStr(conf)) && (!IsEmptyStr(buf)) );

       return(conf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetUser ( struct ctdluser usbuf,
char *  name 
)

Definition at line 118 of file user_ops.c.

{
       return CtdlGetUserLen(usbuf, name, cutuserkey(name));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetUserByNumber ( struct ctdluser usbuf,
long  number 
)

Definition at line 413 of file user_ops.c.

{
       struct cdbdata *cdbun;
       int r;

       cdbun = cdb_fetch(CDB_USERSBYNUMBER, &number, sizeof(long));
       if (cdbun == NULL) {
              CON_syslog(LOG_INFO, "User %ld not found\n", number);
              return(-1);
       }

       CON_syslog(LOG_INFO, "User %ld maps to %s\n", number, cdbun->ptr);
       r = CtdlGetUser(usbuf, cdbun->ptr);
       cdb_free(cdbun);
       return(r);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetUserLen ( struct ctdluser usbuf,
const char *  name,
long  len 
)

Definition at line 91 of file user_ops.c.

{

       char usernamekey[USERNAME_SIZE];
       struct cdbdata *cdbus;

       if (usbuf != NULL) {
              memset(usbuf, 0, sizeof(struct ctdluser));
       }

       makeuserkey(usernamekey, name, len);
       cdbus = cdb_fetch(CDB_USERS, usernamekey, strlen(usernamekey));

       if (cdbus == NULL) { /* user not found */
              return(1);
       }
       if (usbuf != NULL) {
              memcpy(usbuf, cdbus->ptr,
                     ((cdbus->len > sizeof(struct ctdluser)) ?
                      sizeof(struct ctdluser) : cdbus->len));
       }
       cdb_free(cdbus);

       return (0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlGetUserLock ( struct ctdluser usbuf,
char *  name 
)

Definition at line 127 of file user_ops.c.

{
       int retcode;

       retcode = CtdlGetUser(usbuf, name);
       if (retcode == 0) {
              begin_critical_section(S_USERS);
       }
       return (retcode);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlIsNonEditable ( struct ctdlroom qrbuf)

Definition at line 664 of file room_ops.c.

{

       /* Mail> rooms are non-editable */
       if ( (qrbuf->QRflags & QR_MAILBOX)
            && (!strcasecmp(&qrbuf->QRname[11], MAILROOM)) )
              return (1);

       /* Everything else is editable */
       return (0);
}

Here is the caller graph for this function:

int CtdlIsSingleUser ( void  )

Definition at line 132 of file context.c.

{
       if (want_single_user)
       {
              /* check for only one context here */
              if (num_sessions == 1)
                     return TRUE;
       }
       return FALSE;
}
int CtdlIsUserLoggedIn ( char *  user_name)

Definition at line 212 of file context.c.

{
       CitContext *cptr;
       int ret = 0;

       begin_critical_section (S_SESSION_TABLE);
       for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
              if (!strcasecmp(cptr->user.fullname, user_name)) {
                     ret = 1;
                     break;
              }
       }
       end_critical_section(S_SESSION_TABLE);
       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlIsUserLoggedInByNum ( long  usernum)

Definition at line 237 of file context.c.

{
       CitContext *cptr;
       int ret = 0;

       begin_critical_section(S_SESSION_TABLE);
       for (cptr = ContextList; cptr != NULL; cptr = cptr->next) {
              if (cptr->user.usernum == usernum) {
                     ret = 1;
              }
       }
       end_critical_section(S_SESSION_TABLE);
       return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

long CtdlLocateMessageByEuid ( char *  euid,
struct ctdlroom qrbuf 
)

Definition at line 96 of file euidindex.c.

                                                                 {
       char *key;
       int key_len;
       struct cdbdata *cdb_euid;
       long msgnum = (-1L);

       syslog(LOG_DEBUG, "Searching for EUID <%s> in <%s>\n", euid, qrbuf->QRname);

       key_len = strlen(euid) + sizeof(long) + 1;
       key = malloc(key_len);
       memcpy(key, &qrbuf->QRnumber, sizeof(long));
       strcpy(&key[sizeof(long)], euid);

       cdb_euid = cdb_fetch(CDB_EUIDINDEX, key, key_len);
       free(key);

       if (cdb_euid == NULL) {
              msgnum = (-1L);
       }
       else {
              /* The first (sizeof long) of the record is what we're
               * looking for.  Throw away the rest.
               */
              memcpy(&msgnum, cdb_euid->ptr, sizeof(long));
              cdb_free(cdb_euid);
       }
       syslog(LOG_DEBUG, "returning msgnum = %ld\n", msgnum);
       return(msgnum);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlLoginExistingUser ( char *  authname,
const char *  username 
)

Definition at line 528 of file user_ops.c.

{
       char username[SIZ];
       int found_user;
       long len;

       CON_syslog(LOG_DEBUG, "CtdlLoginExistingUser(%s, %s)\n", authname, trythisname);

       if ((CC->logged_in)) {
              return login_already_logged_in;
       }

       if (trythisname == NULL) return login_not_found;
       
       if (!strncasecmp(trythisname, "SYS_", 4))
       {
              CON_syslog(LOG_DEBUG, "System user \"%s\" is not allowed to log in.\n", trythisname);
              return login_not_found;
       }

       /* If a "master user" is defined, handle its authentication if specified */
       CC->is_master = 0;
       if (strlen(config.c_master_user) > 0) if (strlen(config.c_master_pass) > 0) if (authname) {
              if (!strcasecmp(authname, config.c_master_user)) {
                     CC->is_master = 1;
              }
       }

       /* Continue attempting user validation... */
       safestrncpy(username, trythisname, sizeof (username));
       striplt(username);
       len = cutuserkey(username);

       if (IsEmptyStr(username)) {
              return login_not_found;
       }

       if (config.c_auth_mode == AUTHMODE_HOST) {

              /* host auth mode */

              struct passwd pd;
              struct passwd *tempPwdPtr;
              char pwdbuffer[256];
       
              CON_syslog(LOG_DEBUG, "asking host about <%s>\n", username);
#ifdef HAVE_GETPWNAM_R
#ifdef SOLARIS_GETPWUID
              CON_syslog(LOG_DEBUG, "Calling getpwnam_r()\n");
              tempPwdPtr = getpwnam_r(username, &pd, pwdbuffer, sizeof pwdbuffer);
#else // SOLARIS_GETPWUID
              CONM_syslog(LOG_DEBUG, "Calling getpwnam_r()\n");
              getpwnam_r(username, &pd, pwdbuffer, sizeof pwdbuffer, &tempPwdPtr);
#endif // SOLARIS_GETPWUID
#else // HAVE_GETPWNAM_R
              CON_syslog(LOG_DEBUG, "SHOULD NEVER GET HERE!!!\n");
              tempPwdPtr = NULL;
#endif // HAVE_GETPWNAM_R
              if (tempPwdPtr == NULL) {
                     CON_syslog(LOG_DEBUG, "no such user <%s>\n", username);
                     return login_not_found;
              }
       
              /* Locate the associated Citadel account.
               * If not found, make one attempt to create it.
               */
              found_user = getuserbyuid(&CC->user, pd.pw_uid);
              CON_syslog(LOG_DEBUG, "found it: uid=%ld, gecos=%s here: %d\n",
                     (long)pd.pw_uid, pd.pw_gecos, found_user);
              if (found_user != 0) {
                     len = cutuserkey(username);
                     create_user(username, len, 0);
                     found_user = getuserbyuid(&CC->user, pd.pw_uid);
              }

       }

#ifdef HAVE_LDAP
       else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {
       
              /* LDAP auth mode */

              uid_t ldap_uid;
              char ldap_cn[256];
              char ldap_dn[256];

              found_user = CtdlTryUserLDAP(username, ldap_dn, sizeof ldap_dn, ldap_cn, sizeof ldap_cn, &ldap_uid);
              if (found_user != 0) {
                     return login_not_found;
              }

              found_user = getuserbyuid(&CC->user, ldap_uid);
              if (found_user != 0) {
                     create_user(username, len, 0);
                     found_user = getuserbyuid(&CC->user, ldap_uid);
              }

              if (found_user == 0) {
                     if (CC->ldap_dn != NULL) free(CC->ldap_dn);
                     CC->ldap_dn = strdup(ldap_dn);
              }

       }
#endif

       else {
              /* native auth mode */

              struct recptypes *valid = NULL;
       
              /* First, try to log in as if the supplied name is a display name */
              found_user = CtdlGetUser(&CC->user, username);
       
              /* If that didn't work, try to log in as if the supplied name
              * is an e-mail address
              */
              if (found_user != 0) {
                     valid = validate_recipients(username, NULL, 0);
                     if (valid != NULL) {
                            if (valid->num_local == 1) {
                                   found_user = CtdlGetUser(&CC->user, valid->recp_local);
                            }
                            free_recipients(valid);
                     }
              }
       }

       /* Did we find something? */
       if (found_user == 0) {
              if (((CC->nologin)) && (CC->user.axlevel < AxAideU)) {
                     return login_too_many_users;
              } else {
                     safestrncpy(CC->curr_user, CC->user.fullname,
                                   sizeof CC->curr_user);
                     return login_ok;
              }
       }
       return login_not_found;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlMailboxName ( char *  buf,
size_t  n,
const struct ctdluser who,
const char *  prefix 
)

Definition at line 365 of file user_ops.c.

{
       snprintf(buf, n, "%010ld.%s", who->usernum, prefix);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlModuleDoSearch ( int *  num_msgs,
long **  search_msgs,
const char *  search_string,
const char *  func_name 
)

Definition at line 1318 of file serv_extensions.c.

{
       SearchFunctionHook *fcn = NULL;

       for (fcn = SearchFunctionHookTable; fcn != NULL; fcn = fcn->next) {
              if (!func_name || !strcmp(func_name, fcn->name)) {
                     (*fcn->fcn_ptr) (num_msgs, search_msgs, search_string);
                     return;
              }
       }
       *num_msgs = 0;
}

Here is the caller graph for this function:

void CtdlModuleStartCryptoMsgs ( char *  ok_response,
char *  nosup_response,
char *  error_response 
)

Definition at line 1462 of file serv_extensions.c.

{
#ifdef HAVE_OPENSSL
       CtdlStartTLS (ok_response, nosup_response, error_response);
#endif
}

Here is the caller graph for this function:

void CtdlPutFloor ( struct floor flbuf,
int  floor_num 
)

Definition at line 540 of file room_ops.c.

{
       /* If we've cached this, clear it out, 'cuz it's WRONG now! */
       begin_critical_section(S_FLOORCACHE);
       if (floorcache[floor_num] != NULL) {
              free(floorcache[floor_num]);
              floorcache[floor_num] = malloc(sizeof(struct floor));
              memcpy(floorcache[floor_num], flbuf, sizeof(struct floor));
       }
       end_critical_section(S_FLOORCACHE);

       cdb_store(CDB_FLOORTAB, &floor_num, sizeof(int),
                flbuf, sizeof(struct floor));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlPutFloorLock ( struct floor flbuf,
int  floor_num 
)

Definition at line 560 of file room_ops.c.

{

       CtdlPutFloor(flbuf, floor_num);
       end_critical_section(S_FLOORTAB);

}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlPutRoom ( struct ctdlroom )

Definition at line 379 of file room_ops.c.

                                         {
       b_putroom(qrbuf, qrbuf->QRname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlPutRoomLock ( struct ctdlroom qrbuf)

Definition at line 396 of file room_ops.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlPutSysConfig ( char *  sysconfname,
char *  sysconfdata 
)

Definition at line 5375 of file msgbase.c.

                                                            {
       CtdlWriteObject(SYSCONFIGROOM, sysconfname, sysconfdata, (strlen(sysconfdata)+1), NULL, 0, 1, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlPutUser ( struct ctdluser usbuf)

Definition at line 151 of file user_ops.c.

{
       char usernamekey[USERNAME_SIZE];

       makeuserkey(usernamekey, 
                  usbuf->fullname, 
                  cutuserkey(usbuf->fullname));

       usbuf->version = REV_LEVEL;
       cdb_store(CDB_USERS,
                usernamekey, strlen(usernamekey),
                usbuf, sizeof(struct ctdluser));

}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlPutUserLock ( struct ctdluser usbuf)

Definition at line 179 of file user_ops.c.

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlRegisterCleanupHook ( void(*)(void)  fcn_ptr)

Definition at line 480 of file serv_extensions.c.

{

       CleanupFunctionHook *newfcn;

       newfcn = (CleanupFunctionHook *)
           malloc(sizeof(CleanupFunctionHook));
       newfcn->next = CleanupHookTable;
       newfcn->h_function_pointer = fcn_ptr;
       CleanupHookTable = newfcn;

       MODM_syslog(LOG_DEBUG, "Registered a new cleanup function\n");
}

Here is the caller graph for this function:

void CtdlRegisterDeleteHook ( void(*)(char *, long)  handler)

Definition at line 909 of file serv_extensions.c.

{
       DeleteFunctionHook *newfcn;

       newfcn = (DeleteFunctionHook *)
           malloc(sizeof(DeleteFunctionHook));
       newfcn->next = DeleteHookTable;
       newfcn->h_function_pointer = handler;
       DeleteHookTable = newfcn;

       MODM_syslog(LOG_DEBUG, "Registered a new delete function\n");
}

Here is the caller graph for this function:

int CtdlRegisterDirectoryServiceFunc ( int(*)(char *cn, char *ou, void **object)  func,
int  cmd,
char *  module 
)
void CtdlRegisterEVCleanupHook ( void(*)(void)  fcn_ptr)

Definition at line 539 of file serv_extensions.c.

{

       CleanupFunctionHook *newfcn;

       newfcn = (CleanupFunctionHook *)
           malloc(sizeof(CleanupFunctionHook));
       newfcn->next = EVCleanupHookTable;
       newfcn->h_function_pointer = fcn_ptr;
       EVCleanupHookTable = newfcn;

       MODM_syslog(LOG_DEBUG, "Registered a new cleanup function\n");
}

Here is the caller graph for this function:

void CtdlRegisterFixedOutputHook ( char *  content_type,
void(*)(char *supplied_data, int len)  output_function 
)

Here is the caller graph for this function:

void CtdlRegisterMaintenanceThread ( char *  name,
void *(*)(void *arg)  thread_proc 
)
void CtdlRegisterMessageHook ( int(*)(struct CtdlMessage *)  handler,
int  EventType 
)

Definition at line 731 of file serv_extensions.c.

{

       MessageFunctionHook *newfcn;

       newfcn = (MessageFunctionHook *)
           malloc(sizeof(MessageFunctionHook));
       newfcn->next = MessageHookTable;
       newfcn->h_function_pointer = handler;
       newfcn->eventtype = EventType;
       MessageHookTable = newfcn;

       MOD_syslog(LOG_DEBUG, "Registered a new message function (type %d)\n",
                 EventType);
}

Here is the caller graph for this function:

void CtdlRegisterNetprocHook ( int(*)(struct CtdlMessage *, char *)  handler)

Definition at line 851 of file serv_extensions.c.

{
       NetprocFunctionHook *newfcn;

       newfcn = (NetprocFunctionHook *)
           malloc(sizeof(NetprocFunctionHook));
       newfcn->next = NetprocHookTable;
       newfcn->h_function_pointer = handler;
       NetprocHookTable = newfcn;

       MODM_syslog(LOG_DEBUG, "Registered a new netproc function\n");
}

Here is the caller graph for this function:

void CtdlRegisterProtoHook ( void(*)(char *)  handler,
char *  cmd,
char *  desc 
)

Definition at line 450 of file serv_extensions.c.

{
       ProtoFunctionHook *p;

       if (ProtoHookList == NULL)
              ProtoHookList = NewHash (1, FourHash);


       p = (ProtoFunctionHook *)
              malloc(sizeof(ProtoFunctionHook));

       if (p == NULL) {
              fprintf(stderr, "can't malloc new ProtoFunctionHook\n");
              exit(EXIT_FAILURE);
       }
       p->handler = handler;
       p->cmd = cmd;
       p->desc = desc;

       Put(ProtoHookList, cmd, 4, p, NULL);
       MOD_syslog(LOG_DEBUG, "Registered server command %s (%s)\n", cmd, desc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlRegisterRoomHook ( int(*)(struct ctdlroom *)  fcn_ptr)

Definition at line 794 of file serv_extensions.c.

{
       RoomFunctionHook *newfcn;

       newfcn = (RoomFunctionHook *)
           malloc(sizeof(RoomFunctionHook));
       newfcn->next = RoomHookTable;
       newfcn->fcn_ptr = fcn_ptr;
       RoomHookTable = newfcn;

       MODM_syslog(LOG_DEBUG, "Registered a new room function\n");
}

Here is the caller graph for this function:

void CtdlRegisterSearchFuncHook ( void(*)(int *, long **, const char *)  fcn_ptr,
char *  name 
)

Definition at line 1260 of file serv_extensions.c.

{
       SearchFunctionHook *newfcn;

       if (!name || !fcn_ptr) {
              return;
       }
       
       newfcn = (SearchFunctionHook *)
           malloc(sizeof(SearchFunctionHook));
       newfcn->next = SearchFunctionHookTable;
       newfcn->name = name;
       newfcn->fcn_ptr = fcn_ptr;
       SearchFunctionHookTable = newfcn;

       MOD_syslog(LOG_DEBUG, "Registered a new search function (%s)\n", name);
}

Here is the caller graph for this function:

void CtdlRegisterServiceHook ( int  tcp_port,
char *  sockpath,
void(*)(void)  h_greeting_function,
void(*)(void)  h_command_function,
void(*)(void)  h_async_function,
const char *  ServiceName 
)

Definition at line 1108 of file serv_extensions.c.

{
       ServiceFunctionHook *newfcn;
       char *message;
       char error[SIZ];

       strcpy(error, "");
       newfcn = (ServiceFunctionHook *) malloc(sizeof(ServiceFunctionHook));
       message = (char*) malloc (SIZ + SIZ);
       
       newfcn->next = ServiceHookTable;
       newfcn->tcp_port = tcp_port;
       newfcn->sockpath = sockpath;
       newfcn->h_greeting_function = h_greeting_function;
       newfcn->h_command_function = h_command_function;
       newfcn->h_async_function = h_async_function;
       newfcn->ServiceName = ServiceName;

       if (sockpath != NULL) {
              newfcn->msock = ctdl_uds_server(sockpath, config.c_maxsessions, error);
              snprintf(message, SIZ, "Unix domain socket '%s': ", sockpath);
       }
       else if (tcp_port <= 0) {   /* port -1 to disable */
              MOD_syslog(LOG_INFO, "Service %s has been manually disabled, skipping\n", ServiceName);
              free (message);
              free(newfcn);
              return;
       }
       else {
              newfcn->msock = ctdl_tcp_server(config.c_ip_addr,
                                         tcp_port,
                                         config.c_maxsessions, 
                                         error);
              snprintf(message, SIZ, "TCP port %s:%d: (%s) ", 
                      config.c_ip_addr, tcp_port, ServiceName);
       }

       if (newfcn->msock > 0) {
              ServiceHookTable = newfcn;
              strcat(message, "registered.");
              MOD_syslog(LOG_INFO, "%s\n", message);
       }
       else {
              AddPortError(message, error);
              strcat(message, "FAILED.");
              MOD_syslog(LOG_CRIT, "%s\n", message);
              free(newfcn);
       }
       free(message);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlRegisterSessionHook ( void(*)(void)  fcn_ptr,
int  EventType,
int  Priority 
)

Definition at line 599 of file serv_extensions.c.

{
       SessionFunctionHook *newfcn;

       newfcn = (SessionFunctionHook *)
           malloc(sizeof(SessionFunctionHook));
       newfcn->Priority = Priority;
       newfcn->h_function_pointer = fcn_ptr;
       newfcn->eventtype = EventType;

       SessionFunctionHook **pfcn;
       pfcn = &SessionHookTable;
       while ((*pfcn != NULL) && 
              ((*pfcn)->Priority < newfcn->Priority) &&
              ((*pfcn)->next != NULL))
              pfcn = &(*pfcn)->next;
              
       newfcn->next = *pfcn;
       *pfcn = newfcn;
       
       MOD_syslog(LOG_DEBUG, "Registered a new session function (type %d Priority %d)\n",
                 EventType, Priority);
}

Here is the caller graph for this function:

void CtdlRegisterUserHook ( void(*)(struct ctdluser *)  fcn_ptr,
int  EventType 
)

Here is the caller graph for this function:

void CtdlRegisterXmsgHook ( int(*)(char *, char *, char *, char *)  fcn_ptr,
int  order 
)

Definition at line 1047 of file serv_extensions.c.

{

       XmsgFunctionHook *newfcn;

       newfcn = (XmsgFunctionHook *) malloc(sizeof(XmsgFunctionHook));
       newfcn->next = XmsgHookTable;
       newfcn->order = order;
       newfcn->h_function_pointer = fcn_ptr;
       XmsgHookTable = newfcn;
       MOD_syslog(LOG_DEBUG, "Registered a new x-msg function (priority %d)\n", order);
}

Here is the caller graph for this function:

int CtdlRenameRoom ( char *  old_name,
char *  new_name,
int  new_floor 
)

Definition at line 1362 of file room_ops.c.

                                                                  {
       int old_floor = 0;
       struct ctdlroom qrbuf;
       struct ctdlroom qrtmp;
       int ret = 0;
       struct floor *fl;
       struct floor flbuf;
       long owner = 0L;
       char actual_old_name[ROOMNAMELEN];

       syslog(LOG_DEBUG, "CtdlRenameRoom(%s, %s, %d)\n",
              old_name, new_name, new_floor);

       if (new_floor >= 0) {
              fl = CtdlGetCachedFloor(new_floor);
              if ((fl->f_flags & F_INUSE) == 0) {
                     return(crr_invalid_floor);
              }
       }

       begin_critical_section(S_ROOMS);

       if ( (CtdlGetRoom(&qrtmp, new_name) == 0) 
          && (strcasecmp(new_name, old_name)) ) {
              ret = crr_already_exists;
       }

       else if (CtdlGetRoom(&qrbuf, old_name) != 0) {
              ret = crr_room_not_found;
       }

       else if ( (CC->user.axlevel < AxAideU) && (!CC->internal_pgm)
                && (CC->user.usernum != qrbuf.QRroomaide)
                && ( (((qrbuf.QRflags & QR_MAILBOX) == 0) || (atol(qrbuf.QRname) != CC->user.usernum))) )  {
              ret = crr_access_denied;
       }

       else if (CtdlIsNonEditable(&qrbuf)) {
              ret = crr_noneditable;
       }

       else {
              /* Rename it */
              safestrncpy(actual_old_name, qrbuf.QRname, sizeof actual_old_name);
              if (qrbuf.QRflags & QR_MAILBOX) {
                     owner = atol(qrbuf.QRname);
              }
              if ( (owner > 0L) && (atol(new_name) == 0L) ) {
                     snprintf(qrbuf.QRname, sizeof(qrbuf.QRname),
                                   "%010ld.%s", owner, new_name);
              }
              else {
                     safestrncpy(qrbuf.QRname, new_name,
                                          sizeof(qrbuf.QRname));
              }

              /* Reject change of floor for baseroom/aideroom */
              if (!strncasecmp(old_name, config.c_baseroom, ROOMNAMELEN) ||
                  !strncasecmp(old_name, config.c_aideroom, ROOMNAMELEN)) {
                     new_floor = 0;
              }

              /* Take care of floor stuff */
              old_floor = qrbuf.QRfloor;
              if (new_floor < 0) {
                     new_floor = old_floor;
              }
              qrbuf.QRfloor = new_floor;
              CtdlPutRoom(&qrbuf);

              begin_critical_section(S_CONFIG);
       
              /* If baseroom/aideroom name changes, update config */
              if (!strncasecmp(old_name, config.c_baseroom, ROOMNAMELEN)) {
                     safestrncpy(config.c_baseroom, new_name, ROOMNAMELEN);
                     put_config();
              }
              if (!strncasecmp(old_name, config.c_aideroom, ROOMNAMELEN)) {
                     safestrncpy(config.c_aideroom, new_name, ROOMNAMELEN);
                     put_config();
              }
       
              end_critical_section(S_CONFIG);
       
              /* If the room name changed, then there are now two room
               * records, so we have to delete the old one.
               */
              if (strcasecmp(new_name, old_name)) {
                     b_deleteroom(actual_old_name);
              }

              ret = crr_ok;
       }

       end_critical_section(S_ROOMS);

       /* Adjust the floor reference counts if necessary */
       if (new_floor != old_floor) {
              lgetfloor(&flbuf, old_floor);
              --flbuf.f_ref_count;
              lputfloor(&flbuf, old_floor);
              syslog(LOG_DEBUG, "Reference count for floor %d is now %d\n", old_floor, flbuf.f_ref_count);
              lgetfloor(&flbuf, new_floor);
              ++flbuf.f_ref_count;
              lputfloor(&flbuf, new_floor);
              syslog(LOG_DEBUG, "Reference count for floor %d is now %d\n", new_floor, flbuf.f_ref_count);
       }

       /* ...and everybody say "YATTA!" */       
       return(ret);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlRoomAccess ( struct ctdlroom roombuf,
struct ctdluser userbuf,
int *  result,
int *  view 
)

Definition at line 65 of file room_ops.c.

{
       int retval = 0;
       visit vbuf;
       int is_me = 0;
       int is_guest = 0;

       if (userbuf == &CC->user) {
              is_me = 1;
       }

       if ((is_me) && (config.c_guest_logins) && (!CC->logged_in)) {
              is_guest = 1;
       }

       /* for internal programs, always do everything */
       if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) {
              retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED);
              vbuf.v_view = 0;
              goto SKIP_EVERYTHING;
       }

       /* If guest mode is enabled, always grant access to the Lobby */
       if ((is_guest) && (!strcasecmp(roombuf->QRname, BASEROOM))) {
              retval = (UA_KNOWN | UA_GOTOALLOWED);
              vbuf.v_view = 0;
              goto SKIP_EVERYTHING;
       }

       /* Locate any applicable user/room relationships */
       if (is_guest) {
              memset(&vbuf, 0, sizeof vbuf);
       }
       else {
              CtdlGetRelationship(&vbuf, userbuf, roombuf);
       }

       /* Force the properties of the Aide room */
       if (!strcasecmp(roombuf->QRname, config.c_aideroom)) {
              if (userbuf->axlevel >= AxAideU) {
                     retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
              } else {
                     retval = 0;
              }
              goto NEWMSG;
       }

       /* If this is a public room, it's accessible... */
       if (   ((roombuf->QRflags & QR_PRIVATE) == 0) 
              && ((roombuf->QRflags & QR_MAILBOX) == 0)
       ) {
              retval = retval | UA_KNOWN | UA_GOTOALLOWED;
       }

       /* If this is a preferred users only room, check access level */
       if (roombuf->QRflags & QR_PREFONLY) {
              if (userbuf->axlevel < AxPrefU) {
                     retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
              }
       }

       /* For private rooms, check the generation number matchups */
       if (   (roombuf->QRflags & QR_PRIVATE) 
              && ((roombuf->QRflags & QR_MAILBOX) == 0)
       ) {

              /* An explicit match means the user belongs in this room */
              if (vbuf.v_flags & V_ACCESS) {
                     retval = retval | UA_KNOWN | UA_GOTOALLOWED;
              }
              /* Otherwise, check if this is a guess-name or passworded
               * room.  If it is, a goto may at least be attempted
               */
              else if (     (roombuf->QRflags & QR_PRIVATE)
                            || (roombuf->QRflags & QR_PASSWORDED)
              ) {
                     retval = retval & ~UA_KNOWN;
                     retval = retval | UA_GOTOALLOWED;
              }
       }

       /* For mailbox rooms, also check the namespace */
       /* Also, mailbox owners can delete their messages */
       if ( (roombuf->QRflags & QR_MAILBOX) && (atol(roombuf->QRname) != 0)) {
              if (userbuf->usernum == atol(roombuf->QRname)) {
                     retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
              }
              /* An explicit match means the user belongs in this room */
              if (vbuf.v_flags & V_ACCESS) {
                     retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
              }
       }

       /* For non-mailbox rooms... */
       else {

              /* User is allowed to post in the room unless:
               * - User is not validated
               * - User has no net privileges and it is a shared network room
               * - It is a read-only room
               * - It is a blog room (in which case we only allow replies to existing messages)
               */
              int post_allowed = 1;
              int reply_allowed = 1;
              if (userbuf->axlevel < AxProbU) {
                     post_allowed = 0;
                     reply_allowed = 0;
              }
              if ((userbuf->axlevel < AxNetU) && (roombuf->QRflags & QR_NETWORK)) {
                     post_allowed = 0;
                     reply_allowed = 0;
              }
              if (roombuf->QRflags & QR_READONLY) {
                     post_allowed = 0;
                     reply_allowed = 0;
              }
              if (roombuf->QRdefaultview == VIEW_BLOG) {
                     post_allowed = 0;
              }
              if (post_allowed) {
                     retval = retval | UA_POSTALLOWED | UA_REPLYALLOWED;
              }
              if (reply_allowed) {
                     retval = retval | UA_REPLYALLOWED;
              }

              /* If "collaborative deletion" is active for this room, any user who can post
               * is also allowed to delete
               */
              if (roombuf->QRflags2 & QR2_COLLABDEL) {
                     if (retval & UA_POSTALLOWED) {
                            retval = retval | UA_DELETEALLOWED;
                     }
              }

       }

       /* Check to see if the user has forgotten this room */
       if (vbuf.v_flags & V_FORGET) {
              retval = retval & ~UA_KNOWN;
              if (   ( ((roombuf->QRflags & QR_PRIVATE) == 0) 
                     && ((roombuf->QRflags & QR_MAILBOX) == 0)
              ) || ( (roombuf->QRflags & QR_MAILBOX) 
                     && (atol(roombuf->QRname) == CC->user.usernum))
              ) {
                     retval = retval | UA_ZAPPED;
              }
       }

       /* If user is explicitly locked out of this room, deny everything */
       if (vbuf.v_flags & V_LOCKOUT) {
              retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED & ~UA_REPLYALLOWED;
       }

       /* Aides get access to all private rooms */
       if (   (userbuf->axlevel >= AxAideU)
              && ((roombuf->QRflags & QR_MAILBOX) == 0)
       ) {
              if (vbuf.v_flags & V_FORGET) {
                     retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
              }
              else {
                     retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
              }
       }

       /* Aides can gain access to mailboxes as well, but they don't show
        * by default.
        */
       if (   (userbuf->axlevel >= AxAideU)
              && (roombuf->QRflags & QR_MAILBOX)
       ) {
              retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
       }

       /* Aides and Room Aides have admin privileges */
       if (   (userbuf->axlevel >= AxAideU)
              || (userbuf->usernum == roombuf->QRroomaide)
       ) {
              retval = retval | UA_ADMINALLOWED | UA_DELETEALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
       }

NEWMSG:       /* By the way, we also check for the presence of new messages */
       if (is_msg_in_sequence_set(vbuf.v_seen, roombuf->QRhighest) == 0) {
              retval = retval | UA_HASNEWMSGS;
       }

       /* System rooms never show up in the list. */
       if (roombuf->QRflags2 & QR2_SYSTEM) {
              retval = retval & ~UA_KNOWN;
       }

SKIP_EVERYTHING:
       /* Now give the caller the information it wants. */
       if (result != NULL) *result = retval;
       if (view != NULL) *view = vbuf.v_view;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlScheduleRoomForDeletion ( struct ctdlroom qrbuf)

Definition at line 1713 of file room_ops.c.

{
       char old_name[ROOMNAMELEN];
       static int seq = 0;

       syslog(LOG_NOTICE, "Scheduling room <%s> for deletion\n",
              qrbuf->QRname);

       safestrncpy(old_name, qrbuf->QRname, sizeof old_name);

       CtdlGetRoom(qrbuf, qrbuf->QRname);

       /* Turn the room into a private mailbox owned by a user who doesn't
        * exist.  This will immediately make the room invisible to everyone,
        * and qualify the room for purging.
        */
       snprintf(qrbuf->QRname, sizeof qrbuf->QRname, "9999999999.%08lx.%04d.%s",
              time(NULL),
              ++seq,
              old_name
       );
       qrbuf->QRflags |= QR_MAILBOX;
       time(&qrbuf->QRgen); /* Use a timestamp as the new generation number  */

       CtdlPutRoom(qrbuf);

       b_deleteroom(old_name);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlSetRelationship ( visit newvisit,
struct ctdluser rel_user,
struct ctdlroom rel_room 
)

Definition at line 307 of file user_ops.c.

{


       /* We don't use these in Citadel because they're implicit by the
        * index, but they must be present if the database is exported.
        */
       newvisit->v_roomnum = rel_room->QRnumber;
       newvisit->v_roomgen = rel_room->QRgen;
       newvisit->v_usernum = rel_user->usernum;

       put_visit(newvisit);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlShutdownServiceHooks ( void  )

Definition at line 1210 of file serv_extensions.c.

{
       /* sort of a duplicate of close_masters() but called earlier */
       ServiceFunctionHook *cur;

       cur = ServiceHookTable;
       while (cur != NULL) 
       {
              if (cur->msock != -1)
              {
                     close(cur->msock);
                     cur->msock = -1;
                     if (cur->sockpath != NULL){
                            MOD_syslog(LOG_INFO, "[%s] Closed UNIX domain socket %s\n",
                                      cur->ServiceName,
                                      cur->sockpath);
                            unlink(cur->sockpath);
                     } else {
                            MOD_syslog(LOG_INFO, "[%s] closing service\n", 
                                      cur->ServiceName);
                     }
              }
              cur = cur->next;
       }
}

Here is the caller graph for this function:

int CtdlTryPassword ( const char *  password,
long  len 
)

Definition at line 927 of file user_ops.c.

{
       int code;
       CitContext *CCC = CC;

       if ((CCC->logged_in)) {
              CONM_syslog(LOG_WARNING, "CtdlTryPassword: already logged in\n");
              return pass_already_logged_in;
       }
       if (!strcmp(CCC->curr_user, NLI)) {
              CONM_syslog(LOG_WARNING, "CtdlTryPassword: no user selected\n");
              return pass_no_user;
       }
       if (CtdlGetUser(&CCC->user, CCC->curr_user)) {
              CONM_syslog(LOG_ERR, "CtdlTryPassword: internal error\n");
              return pass_internal_error;
       }
       if (password == NULL) {
              CONM_syslog(LOG_INFO, "CtdlTryPassword: NULL password string supplied\n");
              return pass_wrong_password;
       }

       if (CCC->is_master) {
              code = strcmp(password, config.c_master_pass);
       }

       else if (config.c_auth_mode == AUTHMODE_HOST) {

              /* host auth mode */

              if (validpw(CCC->user.uid, password)) {
                     code = 0;

                     /*
                      * sooper-seekrit hack: populate the password field in the
                      * citadel database with the password that the user typed,
                      * if it's correct.  This allows most sites to convert from
                      * host auth to native auth if they want to.  If you think
                      * this is a security hazard, comment it out.
                      */

                     CtdlGetUserLock(&CCC->user, CCC->curr_user);
                     safestrncpy(CCC->user.password, password, sizeof CCC->user.password);
                     CtdlPutUserLock(&CCC->user);

                     /*
                      * (sooper-seekrit hack ends here)
                      */

              }
              else {
                     code = (-1);
              }
       }

#ifdef HAVE_LDAP
       else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) {

              /* LDAP auth mode */

              if ((CCC->ldap_dn) && (!CtdlTryPasswordLDAP(CCC->ldap_dn, password))) {
                     code = 0;
              }
              else {
                     code = (-1);
              }
       }
#endif

       else {

              /* native auth mode */
              char *pw;

              pw = (char*) malloc(len + 1);
              memcpy(pw, password, len + 1);
              strproc(pw);
              strproc(CCC->user.password);
              code = strcasecmp(CCC->user.password, pw);
              if (code != 0) {
                     strproc(pw);
                     strproc(CCC->user.password);
                     code = strcasecmp(CCC->user.password, pw);
              }
              free (pw);
       }

       if (!code) {
              do_login();
              return pass_ok;
       } else {
              CON_syslog(LOG_WARNING, "Bad password specified for <%s> Service <%s> Port <%ld> Remote <%s / %s>\n",
                        CCC->curr_user,
                        CCC->ServiceName,
                        CCC->tcp_port,
                        CCC->cs_host,
                        CCC->cs_addr);


//citserver[5610]: Bad password specified for <willi> Service <citadel-TCP> Remote <PotzBlitz / >

              return pass_wrong_password;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlTrySingleUser ( void  )

Definition at line 103 of file context.c.

{
       int can_do = 0;
       
       begin_critical_section(S_SINGLE_USER);
       if (want_single_user)
              can_do = 0;
       else
       {
              can_do = 1;
              want_single_user = 1;
       }
       end_critical_section(S_SINGLE_USER);
       return can_do;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlUnregisterCleanupHook ( void(*)(void)  fcn_ptr)

Definition at line 495 of file serv_extensions.c.

{
       CleanupFunctionHook *cur, *p, *last;
       last = NULL;
       cur = CleanupHookTable;
       while (cur != NULL)
       {
              if (fcn_ptr == cur->h_function_pointer)
              {
                     MODM_syslog(LOG_DEBUG, "Unregistered cleanup function\n");
                     p = cur->next;

                     free(cur);
                     cur = NULL;

                     if (last != NULL)
                            last->next = p;
                     else 
                            CleanupHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterDeleteHook ( void(*)(char *, long)  handler)

Definition at line 923 of file serv_extensions.c.

{
       DeleteFunctionHook *cur, *p, *last;

       last = NULL;
       cur = DeleteHookTable;
       while (cur != NULL) {
              if (handler == cur->h_function_pointer )
              {
                     MODM_syslog(LOG_DEBUG, "Unregistered delete function\n");
                     p = cur->next;
                     free(cur);

                     if (last != NULL)
                            last->next = p;
                     else
                            DeleteHookTable = p;

                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterEVCleanupHook ( void(*)(void)  fcn_ptr)

Definition at line 554 of file serv_extensions.c.

{
       CleanupFunctionHook *cur, *p, *last;
       last = NULL;
       cur = EVCleanupHookTable;
       while (cur != NULL)
       {
              if (fcn_ptr == cur->h_function_pointer)
              {
                     MODM_syslog(LOG_DEBUG, "Unregistered cleanup function\n");
                     p = cur->next;

                     free(cur);
                     cur = NULL;

                     if (last != NULL)
                            last->next = p;
                     else 
                            EVCleanupHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnRegisterFixedOutputHook ( char *  content_type)
void CtdlUnregisterMessageHook ( int(*)(struct CtdlMessage *)  handler,
int  EventType 
)

Definition at line 749 of file serv_extensions.c.

{
       MessageFunctionHook *cur, *p, *last;
       last = NULL;
       cur = MessageHookTable;
       while (cur != NULL) {
              if ((handler == cur->h_function_pointer) &&
                  (EventType == cur->eventtype))
              {
                     MOD_syslog(LOG_DEBUG, "Unregistered message function (type %d)\n",
                               EventType);
                     p = cur->next;
                     free(cur);
                     cur = NULL;

                     if (last != NULL)
                            last->next = p;
                     else 
                            MessageHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterNetprocHook ( int(*)(struct CtdlMessage *, char *)  handler)

Definition at line 865 of file serv_extensions.c.

{
       NetprocFunctionHook *cur, *p, *last;

       cur = NetprocHookTable;
       last = NULL;

       while (cur != NULL) {
              if (handler == cur->h_function_pointer)
              {
                     MODM_syslog(LOG_DEBUG, "Unregistered netproc function\n");
                     p = cur->next;
                     free(cur);
                     if (last != NULL) {
                            last->next = p;
                     }
                     else {
                            NetprocHookTable = p;
                     }
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterRoomHook ( int(*)(struct ctdlroom *)  fnc_ptr)

Definition at line 808 of file serv_extensions.c.

{
       RoomFunctionHook *cur, *p, *last;
       last = NULL;
       cur = RoomHookTable;
       while (cur != NULL)
       {
              if (fcn_ptr == cur->fcn_ptr) {
                     MODM_syslog(LOG_DEBUG, "Unregistered room function\n");
                     p = cur->next;

                     free(cur);
                     cur = NULL;

                     if (last != NULL)
                            last->next = p;
                     else 
                            RoomHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterServiceHook ( int  tcp_port,
char *  sockpath,
void(*)(void)  h_greeting_function,
void(*)(void)  h_command_function,
void(*)(void)  h_async_function 
)

Definition at line 1165 of file serv_extensions.c.

{
       ServiceFunctionHook *cur, *p, *last;

       last = NULL;
       cur = ServiceHookTable;
       while (cur != NULL) {
              /* This will also remove duplicates if any */
              if (h_greeting_function == cur->h_greeting_function &&
                  h_command_function == cur->h_command_function &&
                  h_async_function == cur->h_async_function &&
                  tcp_port == cur->tcp_port && 
                  !(sockpath && cur->sockpath && strcmp(sockpath, cur->sockpath)) )
              {
                     if (cur->msock > 0)
                            close(cur->msock);
                     if (sockpath) {
                            MOD_syslog(LOG_INFO, "Closed UNIX domain socket %s\n",
                                      sockpath);
                            unlink(sockpath);
                     } else if (tcp_port) {
                            MOD_syslog(LOG_INFO, "Closed TCP port %d\n", tcp_port);
                     } else {
                            MOD_syslog(LOG_INFO, "Unregistered service \"%s\"\n", cur->ServiceName);
                     }
                     p = cur->next;
                     free(cur);
                     if (last != NULL)
                            last->next = p;
                     else
                            ServiceHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterSessionHook ( void(*)(void)  fcn_ptr,
int  EventType 
)

Definition at line 624 of file serv_extensions.c.

{
       SessionFunctionHook *cur, *p, *last;
       last = NULL;
       cur = SessionHookTable;
       while  (cur != NULL) {
              if ((fcn_ptr == cur->h_function_pointer) &&
                  (EventType == cur->eventtype))
              {
                     MOD_syslog(LOG_DEBUG, "Unregistered session function (type %d)\n",
                               EventType);
                     p = cur->next;

                     free(cur);
                     cur = NULL;

                     if (last != NULL)
                            last->next = p;
                     else 
                            SessionHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterUserHook ( void(*)(struct ctdluser *)  fcn_ptr,
int  EventType 
)

Definition at line 686 of file serv_extensions.c.

{
       UserFunctionHook *cur, *p, *last;
       last = NULL;
       cur = UserHookTable;
       while (cur != NULL) {
              if ((fcn_ptr == cur->h_function_pointer) &&
                  (EventType == cur->eventtype))
              {
                     MOD_syslog(LOG_DEBUG, "Unregistered user function (type %d)\n",
                               EventType);
                     p = cur->next;

                     free(cur);
                     cur = NULL;

                     if (last != NULL)
                            last->next = p;
                     else 
                            UserHookTable = p;
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUnregisterXmsgHook ( int(*)(char *, char *, char *, char *)  fcn_ptr,
int  order 
)

Definition at line 1061 of file serv_extensions.c.

{
       XmsgFunctionHook *cur, *p, *last;

       last = NULL;
       cur = XmsgHookTable;
       while (cur != NULL) {
              /* This will also remove duplicates if any */
              if (fcn_ptr == cur->h_function_pointer &&
                  order == cur->order) {
                     MOD_syslog(LOG_DEBUG, "Unregistered x-msg function "
                               "(priority %d)\n", order);
                     p = cur->next;
                     free(cur);

                     if (last != NULL)
                            last->next = p;
                     else
                            XmsgHookTable = p;
                     
                     cur = p;
              }
              else {
                     last = cur;
                     cur = cur->next;
              }
       }
}
void CtdlUserGoto ( char *  where,
int  display_result,
int  transiently,
int *  msgs,
int *  new 
)

Definition at line 923 of file room_ops.c.

{
       struct CitContext *CCC = CC;
       int a;
       int new_messages = 0;
       int old_messages = 0;
       int total_messages = 0;
       int info = 0;
       int rmailflag;
       int raideflag;
       int newmailcount = 0;
       visit vbuf;
       char truncated_roomname[ROOMNAMELEN];
        struct cdbdata *cdbfr;
       long *msglist = NULL;
       int num_msgs = 0;
       unsigned int original_v_flags;
       int num_sets;
       int s;
       char setstr[128], lostr[64], histr[64];
       long lo, hi;
       int is_trash = 0;

       /* If the supplied room name is NULL, the caller wants us to know that
        * it has already copied the room record into CC->room, so
        * we can skip the extra database fetch.
        */
       if (where != NULL) {
              safestrncpy(CCC->room.QRname, where, sizeof CCC->room.QRname);
              CtdlGetRoom(&CCC->room, where);
       }

       /* Take care of all the formalities. */

       begin_critical_section(S_USERS);
       CtdlGetRelationship(&vbuf, &CCC->user, &CCC->room);
       original_v_flags = vbuf.v_flags;

       /* Know the room ... but not if it's the page log room, or if the
        * caller specified that we're only entering this room transiently.
        */
       if ((strcasecmp(CCC->room.QRname, config.c_logpages))
          && (transiently == 0) ) {
              vbuf.v_flags = vbuf.v_flags & ~V_FORGET & ~V_LOCKOUT;
              vbuf.v_flags = vbuf.v_flags | V_ACCESS;
       }
       
       /* Only rewrite the database record if we changed something */
       if (vbuf.v_flags != original_v_flags) {
              CtdlSetRelationship(&vbuf, &CCC->user, &CCC->room);
       }
       end_critical_section(S_USERS);

       /* Check for new mail */
       newmailcount = NewMailCount();

       /* set info to 1 if the user needs to read the room's info file */
       if (CCC->room.QRinfo > vbuf.v_lastseen) {
              info = 1;
       }

        cdbfr = cdb_fetch(CDB_MSGLISTS, &CCC->room.QRnumber, sizeof(long));
        if (cdbfr != NULL) {
              msglist = (long *) cdbfr->ptr;
              cdbfr->ptr = NULL;   /* CtdlUserGoto() now owns this memory */
              num_msgs = cdbfr->len / sizeof(long);
              cdb_free(cdbfr);
       }

       total_messages = 0;
       for (a=0; a<num_msgs; ++a) {
              if (msglist[a] > 0L) ++total_messages;
       }

       num_sets = num_tokens(vbuf.v_seen, ',');
       for (s=0; s<num_sets; ++s) {
              extract_token(setstr, vbuf.v_seen, s, ',', sizeof setstr);

              extract_token(lostr, setstr, 0, ':', sizeof lostr);
              if (num_tokens(setstr, ':') >= 2) {
                     extract_token(histr, setstr, 1, ':', sizeof histr);
                     if (!strcmp(histr, "*")) {
                            snprintf(histr, sizeof histr, "%ld", LONG_MAX);
                     }
              } 
              else {
                     strcpy(histr, lostr);
              }
              lo = atol(lostr);
              hi = atol(histr);

              for (a=0; a<num_msgs; ++a) if (msglist[a] > 0L) {
                     if ((msglist[a] >= lo) && (msglist[a] <= hi)) {
                            ++old_messages;
                            msglist[a] = 0L;
                     }
              }
       }
       new_messages = total_messages - old_messages;

       if (msglist != NULL) free(msglist);

       if (CCC->room.QRflags & QR_MAILBOX)
              rmailflag = 1;
       else
              rmailflag = 0;

       if ((CCC->room.QRroomaide == CCC->user.usernum)
           || (CCC->user.axlevel >= AxAideU))
              raideflag = 1;
       else
              raideflag = 0;

       safestrncpy(truncated_roomname, CCC->room.QRname, sizeof truncated_roomname);
       if ( (CCC->room.QRflags & QR_MAILBOX)
          && (atol(CCC->room.QRname) == CCC->user.usernum) ) {
              safestrncpy(truncated_roomname, &truncated_roomname[11], sizeof truncated_roomname);
       }

       if (!strcasecmp(truncated_roomname, USERTRASHROOM)) {
              is_trash = 1;
       }

       if (retmsgs != NULL) *retmsgs = total_messages;
       if (retnew != NULL) *retnew = new_messages;
       MSG_syslog(LOG_INFO, "<%s> %d new of %d total messages\n",
                 CCC->room.QRname,
                 new_messages, total_messages
              );

       CCC->curr_view = (int)vbuf.v_view;

       if (display_result) {
              cprintf("%d%c%s|%d|%d|%d|%d|%ld|%ld|%d|%d|%d|%d|%d|%d|%d|%d|\n",
                     CIT_OK, CtdlCheckExpress(),
                     truncated_roomname,
                     (int)new_messages,
                     (int)total_messages,
                     (int)info,
                     (int)CCC->room.QRflags,
                     (long)CCC->room.QRhighest,
                     (long)vbuf.v_lastseen,
                     (int)rmailflag,
                     (int)raideflag,
                     (int)newmailcount,
                     (int)CCC->room.QRfloor,
                     (int)vbuf.v_view,
                     (int)CCC->room.QRdefaultview,
                     (int)is_trash,
                     (int)CCC->room.QRflags2
              );
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CtdlUserLogout ( void  )

Definition at line 779 of file user_ops.c.

{
       CitContext *CCC = MyContext();

       CON_syslog(LOG_DEBUG, "CtdlUserLogout() logging out <%s> from session %d",
                 CCC->curr_user, CCC->cs_pid
       );

       /*
        * If there is a download in progress, abort it.
        */
       if (CCC->download_fp != NULL) {
              fclose(CCC->download_fp);
              CCC->download_fp = NULL;
       }

       /*
        * If there is an upload in progress, abort it.
        */
       if (CCC->upload_fp != NULL) {
              abort_upl(CCC);
       }

       /* Run any hooks registered by modules... */
       PerformSessionHooks(EVT_LOGOUT);
       
       /*
        * Clear out some session data.  Most likely, the CitContext for this
        * session is about to get nuked when the session disconnects, but
        * since it's possible to log in again without reconnecting, we cannot
        * make that assumption.
        */
       strcpy(CCC->fake_username, "");
       strcpy(CCC->fake_hostname, "");
       strcpy(CCC->fake_roomname, "");
       CCC->logged_in = 0;

       /* Check to see if the user was deleted whilst logged in and purge them if necessary */
       if ((CCC->user.axlevel == AxDeleted) && (CCC->user.usernum))
              purge_user(CCC->user.fullname);

       /* Clear out the user record in memory so we don't behave like a ghost */
       memset(&CCC->user, 0, sizeof(struct ctdluser));
       CCC->curr_user[0] = 0;
       CCC->is_master = 0;
       CCC->cs_inet_email[0] = 0;
       CCC->cs_inet_other_emails[0] = 0;
       CCC->cs_inet_fn[0] = 0;
       CCC->fake_username[0] = 0;
       CCC->fake_hostname[0] = 0;
       CCC->fake_roomname[0] = 0;
       

       /* Free any output buffers */
       unbuffer_output();
}

Here is the call graph for this function:

Here is the caller graph for this function:

int CtdlWantSingleUser ( void  )

Definition at line 127 of file context.c.

{
       return want_single_user;
}

Here is the caller graph for this function: