+Mon Aug 31 22:47:58 EDT 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
+ * Yanked the citadelapi.c module. This wasn't working out well.
+ * techdocs/citadelapi.txt - began documenting the new API to be used
+ by modules which will be dynamic linked into the server - most of
+ this API is existing server functions.
+ * Added a ForEachUser() function with callback mechanism, and reworked
+ cmd_list() to use it.
+
Sun Aug 30 21:52:43 EDT 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
* Moved all of the gdbm databases to a separate "data" directory.
########################################################################
CLIENT_TARGETS=citadel whobbs
-SERVER_TARGETS=citserver setup citadelapi.a
+SERVER_TARGETS=citserver setup
SERV_MODULES=serv_chat.so
UTIL_TARGETS=aidepost netmailer netproc netsetup msgform \
readlog rcit stats citmail netpoll mailinglist userlist
sysdep.o: sysdep.c citadel.h sysdep.h sysconfig.h ipcdef.h server.h
$(CC) -O $(CFLAGS) -D_REENTRANT -c sysdep.c
-citadelapi.a: citadelapi.o ipc_c_tcp.o serv_info.o
- $(AR) r citadelapi.a citadelapi.o ipc_c_tcp.o serv_info.o
- $(RANLIB) citadelapi.a
-
-citadelapi.o: citadelapi.c citadel.h sysdep.h sysconfig.h ipcdef.h server.h
- $(CC) -O $(CFLAGS) -D_REENTRANT -c citadelapi.c
-
aidepost: aidepost.c config.o citadel.h sysdep.h sysconfig.h ipcdef.h server.h
$(CC) -O $(CFLAGS) aidepost.c config.o $(LFLAGS) -o aidepost
+++ /dev/null
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <time.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include "citadel.h"
-#include "serv_info.h"
-#include "ipc.h"
-#include "citadelapi.h"
-#include "support.h"
-
-
-struct CtdlInternalList {
- struct CtdlInternalList *next;
- char data[256];
- };
-
-
-struct CtdlServerHandle CtdlAppHandle;
-struct CtdlServInfo CtdlAppServInfo;
-struct CtdlRoomInfo CtdlCurrentRoom;
-int CtdlErrno = 0;
-
-void logoff(int exitcode) {
- exit(exitcode);
- }
-
-
-
-/*
- * CtdlInternalNumParms() - discover number of parameters...
- */
-int CtdlInternalNumParms(char *source)
-{
- int a;
- int count = 1;
-
- for (a=0; a<strlen(source); ++a)
- if (source[a]=='|') ++count;
- return(count);
- }
-
-/*
- * CtdlInternalExtract() - extract a parameter from a series of "|" separated
- */
-void CtdlInternalExtract(char *dest, char *source, int parmnum)
-{
- char buf[256];
- int count = 0;
- int n;
-
- if (strlen(source)==0) {
- strcpy(dest,"");
- return;
- }
-
- n = CtdlInternalNumParms(source);
-
- if (parmnum >= n) {
- strcpy(dest,"");
- return;
- }
- strcpy(buf,source);
- if ( (parmnum == 0) && (n == 1) ) {
- strcpy(dest,buf);
- for (n=0; n<strlen(dest); ++n)
- if (dest[n]=='|') dest[n] = 0;
- return;
- }
-
- while (count++ < parmnum) do {
- strcpy(buf,&buf[1]);
- } while( (strlen(buf)>0) && (buf[0]!='|') );
- if (buf[0]=='|') strcpy(buf,&buf[1]);
- for (count = 0; count<strlen(buf); ++count)
- if (buf[count] == '|') buf[count] = 0;
- strcpy(dest,buf);
- }
-
-/*
- * CtdlInternalExtractInt() - Extract an int parm w/o supplying a buffer
- */
-int CtdlInternalExtractInt(char *source, int parmnum)
-{
- char buf[256];
-
- CtdlInternalExtract(buf,source,parmnum);
- return(atoi(buf));
- }
-
-/*
- * CtdlInternalExtractLong() - Extract an long parm w/o supplying a buffer
- */
-long CtdlInternalExtractLong(char *source, long int parmnum)
-{
- char buf[256];
-
- CtdlInternalExtract(buf,source,parmnum);
- return(atol(buf));
- }
-
-
-
-
-
-
-
-
-
-
-
-
-/*
- * Programs linked against the Citadel server extension library need to
- * be called with the following arguments:
- * 0 - program name (as always)
- * 1 - server address (usually 127.0.0.1)
- * 2 - server port number
- * 3 - internal program secret
- * 4 - user name
- * 5 - user password
- * 6 - initial room
- * 7 - associated client session
- *
- */
-
-int
-main(int argc, char *argv[])
-{
- int a;
- char buf[256];
-
- /* We're really not interested in stdio */
- close(0);
- close(1);
- close(2);
-
- /* Bail out if someone tries to run this thing manually */
- if (argc < 3) exit(1);
-
- /* Zeroing out the server handle neatly sets the values of
- * CtdlAppHandle to sane default values. This also holds true
- * for the CtdlCurrentRoom.
- */
- bzero(&CtdlAppHandle, sizeof(struct CtdlServerHandle));
- bzero(&CtdlCurrentRoom, sizeof(struct CtdlRoomInfo));
-
- /* Now parse the command-line arguments fed to us by the server */
- for (a=0; a<argc; ++a) switch(a) {
- case 1: strcpy(CtdlAppHandle.ServerAddress, argv[a]);
- break;
- case 2: CtdlAppHandle.ServerPort = atoi(argv[a]);
- break;
- case 3: strcpy(CtdlAppHandle.ipgmSecret, argv[a]);
- break;
- case 4: strcpy(CtdlAppHandle.UserName, argv[a]);
- break;
- case 5: strcpy(CtdlAppHandle.Password, argv[a]);
- break;
- case 6: strcpy(CtdlAppHandle.InitialRoom, argv[a]);
- break;
- case 7: CtdlAppHandle.AssocClientSession = atoi(argv[a]);
- break;
- }
-
- /* Connect to the server */
- argc = 3;
- attach_to_server(argc, argv);
- serv_gets(buf);
- if (buf[0] != '2') exit(1);
-
- /* Set up the server environment to our liking */
-
- CtdlInternalGetServInfo(&CtdlAppServInfo);
-
- sprintf(buf, "IDEN 0|5|006|CitadelAPI Client");
- serv_puts(buf);
- serv_gets(buf);
-
- if (strlen(CtdlAppHandle.ipgmSecret) > 0) {
- sprintf(buf, "IPGM %s", CtdlAppHandle.ipgmSecret);
- serv_puts(buf);
- serv_gets(buf);
- }
-
- if (strlen(CtdlAppHandle.UserName) > 0) {
- sprintf(buf, "USER %s", CtdlAppHandle.UserName);
- serv_puts(buf);
- serv_gets(buf);
- sprintf(buf, "PASS %s", CtdlAppHandle.Password);
- serv_puts(buf);
- serv_gets(buf);
- }
-
- if (CtdlGotoRoom(CtdlAppHandle.InitialRoom) != 0) {
- CtdlGotoRoom("_BASEROOM_");
- }
-
- /* Now do the loop. */
- CtdlMain();
-
- /* Clean up gracefully and exit. */
- serv_puts("QUIT");
- exit(0);
- }
-
-
-int CtdlGetLastError(void) {
- return CtdlErrno;
- }
-
-
-int CtdlSendExpressMessage(char *ToUser, char *MsgText) {
- char buf[256];
-
- if (strlen(ToUser) + strlen(MsgText) > 248) {
- CtdlErrno = ERROR + TOO_BIG;
- return CtdlErrno;
- }
-
- sprintf(buf, "SEXP %s|%s", ToUser, MsgText);
- serv_puts(buf);
- serv_gets(buf);
-
- CtdlErrno = atoi(buf);
- if (CtdlErrno == OK) CtdlErrno = 0;
- return CtdlErrno;
- }
-
-
-
-int CtdlInternalGetUserParam(char *ParamBuf, int ParamNum, char *WhichUser) {
- char buf[256];
-
- sprintf(buf, "AGUP %s", WhichUser);
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] != '2') return(atoi(buf));
- CtdlInternalExtract(ParamBuf, &buf[4], ParamNum);
- return(0);
- }
-
-
-int CtdlInternalSetUserParam(char *ParamBuf, int ParamNum, char *WhichUser) {
- char buf[256];
- char params[8][256];
- int a;
-
- sprintf(buf, "AGUP %s", WhichUser);
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] != '2') return(atoi(buf));
- for (a=0; a<8; ++a) {
- CtdlInternalExtract(¶ms[a][0], &buf[4], a);
- }
- strcpy(¶ms[ParamNum][0], ParamBuf);
- strcpy(buf, "ASUP ");
- for (a=0; a<8; ++a) {
- strcat(buf, ¶ms[a][0]);
- strcat(buf, "|");
- }
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] != '2') return(atoi(buf));
- return(0);
- }
-
-/*
- 0 - User name
- 1 - Password
- 2 - Flags (see citadel.h)
- 3 - Times called
- 4 - Messages posted
- 5 - Access level
- 6 - User number
- 7 - Timestamp of last call
- */
-
-int CtdlGetUserPassword(char *buf, char *WhichUser) {
- CtdlErrno = CtdlInternalGetUserParam(buf, 1, WhichUser);
- return(CtdlErrno);
- }
-
-int CtdlSetUserPassword(char *buf, char *WhichUser) {
- CtdlErrno = CtdlInternalSetUserParam(buf, 1, WhichUser);
- return(CtdlErrno);
- }
-
-unsigned int CtdlGetUserFlags(char *WhichUser) {
- char buf[256];
- CtdlErrno = CtdlInternalGetUserParam(buf, 2, WhichUser);
- return((CtdlErrno == 0) ? atoi(buf) : (-1));
- }
-
-int CtdlSetUserFlags(unsigned int NewFlags, char *WhichUser) {
- char buf[256];
- sprintf(buf, "%u", NewFlags);
- CtdlErrno = CtdlInternalGetUserParam(buf, 2, WhichUser);
- return(CtdlErrno);
- }
-
-int CtdlGetUserTimesCalled(char *WhichUser) {
- char buf[256];
- CtdlErrno = CtdlInternalGetUserParam(buf, 3, WhichUser);
- return((CtdlErrno == 0) ? atoi(buf) : (-1));
- }
-
-int CtdlSetUserTimesCalled(int NewValue, char *WhichUser) {
- char buf[256];
- sprintf(buf, "%d", NewValue);
- CtdlErrno = CtdlInternalGetUserParam(buf, 3, WhichUser);
- return(CtdlErrno);
- }
-
-int CtdlGetUserMessagesPosted(char *WhichUser) {
- char buf[256];
- CtdlErrno = CtdlInternalGetUserParam(buf, 4, WhichUser);
- return((CtdlErrno == 0) ? atoi(buf) : (-1));
- }
-
-int CtdlSetUserMessagesPosted(int NewValue, char *WhichUser) {
- char buf[256];
- sprintf(buf, "%d", NewValue);
- CtdlErrno = CtdlInternalGetUserParam(buf, 4, WhichUser);
- return(CtdlErrno);
- }
-
-int CtdlGetUserAccessLevel(char *WhichUser) {
- char buf[256];
- CtdlErrno = CtdlInternalGetUserParam(buf, 5, WhichUser);
- return((CtdlErrno == 0) ? atoi(buf) : (-1));
- }
-
-int CtdlSetUserAccessLevel(int NewValue, char *WhichUser) {
- char buf[256];
-
- if ( (NewValue < 0) || (NewValue > 6) ) {
- return(ERROR + ILLEGAL_VALUE);
- }
-
- sprintf(buf, "%d", NewValue);
- CtdlErrno = CtdlInternalGetUserParam(buf, 5, WhichUser);
- return(CtdlErrno);
- }
-
-long CtdlGetUserNumber(char *WhichUser) {
- char buf[256];
- CtdlErrno = CtdlInternalGetUserParam(buf, 6, WhichUser);
- return((CtdlErrno == 0) ? atol(buf) : (-1L));
- }
-
-int CtdlSetUserNumber(long NewValue, char *WhichUser) {
- char buf[256];
- sprintf(buf, "%ld", NewValue);
- CtdlErrno = CtdlInternalGetUserParam(buf, 6, WhichUser);
- return(CtdlErrno);
- }
-
-time_t CtdlGetUserLastCall(char *WhichUser) {
- char buf[256];
- CtdlErrno = CtdlInternalGetUserParam(buf, 7, WhichUser);
- return((CtdlErrno == 0) ? atol(buf) : (time_t)(-1L));
- }
-
-int CtdlSetUserLastCall(time_t NewValue, char *WhichUser) {
- char buf[256];
- sprintf(buf, "%ld", NewValue);
- CtdlErrno = CtdlInternalGetUserParam(buf, 7, WhichUser);
- return(CtdlErrno);
- }
-
-int CtdlForEachUser(int (*CallBack)(char *EachUser)) {
- struct CtdlInternalList *TheList = NULL;
- struct CtdlInternalList *ptr;
- char buf[256];
-
- serv_puts("LIST");
- serv_gets(buf);
- if (buf[0] != '1') return(-1);
-
- while (serv_gets(buf), strcmp(buf, "000")) {
- ptr = (struct CtdlInternalList *)
- malloc(sizeof (struct CtdlInternalList));
- if (ptr != NULL) {
- CtdlInternalExtract(ptr->data, buf, 0);
- ptr->next = TheList;
- TheList = ptr;
- }
- }
-
- while (TheList != NULL) {
- (*CallBack)(TheList->data);
- ptr = TheList->next;
- free(TheList);
- TheList = ptr;
- }
-
- return(0);
- }
-
-
-
-
-
-int CtdlForEachRoom(int (*CallBack)(char *EachRoom)) {
- struct CtdlInternalList *TheList = NULL;
- struct CtdlInternalList *ptr;
- char buf[256];
-
- serv_puts("LKRA");
- serv_gets(buf);
- if (buf[0] != '1') return(-1);
-
- while (serv_gets(buf), strcmp(buf, "000")) {
- ptr = (struct CtdlInternalList *)
- malloc(sizeof (struct CtdlInternalList));
- if (ptr != NULL) {
- CtdlInternalExtract(ptr->data, buf, 0);
- ptr->next = TheList;
- TheList = ptr;
- }
- }
-
- while (TheList != NULL) {
- (*CallBack)(TheList->data);
- ptr = TheList->next;
- free(TheList);
- TheList = ptr;
- }
-
- return(0);
- }
-
-
-
-/*
- * Goto a different room
- */
-int CtdlGotoRoom(char *RoomName) {
- char buf[256];
-
- sprintf(buf, "GOTO %s", RoomName);
- serv_puts(buf);
- serv_gets(buf);
- if (buf[0] != '2') {
- CtdlErrno = atoi(buf);
- return(CtdlErrno);
- }
- extract(CtdlCurrentRoom.RoomName, &buf[4], 0);
- return 0;
- }
char text[MAXWORDBUF];
};
-long finduser(int file, char *name);
char inkey(void);
void sttybbs(int cmd);
int struncmp(char *lstr, char *rstr, int len);
#define IFNAIDE if (axlevel<6)
-long finduser(int file, char *name);
void sttybbs(int cmd);
void extract(char *dest, char *source, int parmnum);
int extract_int(char *source, int parmnum);
}
-int hash(char *str)
-{
- int h = 0;
- int i;
-
- for (i=0; i<strlen(str); ++i) h=h+((i+1)*tolower(str[i]));
- return(h);
- }
-
-long finduser(int file, char *name)
-{
- FILE *fp;
- int uh,fh;
- long pp=0L;
-
- uh=hash(name);
- fp=fopen("hashtab","r");
- while(fread((char *)&fh,sizeof(int),1,fp)>0) {
- if (uh==fh) {
- lseek(file,pp,0);
- return(pp);
- }
- pp = pp + (long)sizeof(struct usersupp);
- }
- fclose(fp);
- return(-1L);
- }
-
-
int alias(char *name) /* process alias and routing info for mail */
{
FILE *fp;
int ka_wait(pid_t *kstatus);
void serv_write(char *buf, int nbytes);
void extract(char *dest, char *source, int parmnum);
-long finduser(int file, char *name);
int haschar(char *st, int ch);
void progress(long int curr, long int cmax);
void citedit(FILE *fp, long int base_pos);
+++ /dev/null
- Yeesh.
-
- This is a rough start at the beginnings of what will eventually become
-something that resembles a draft of the implementation of an API for writing
-Citadel extensions...
-
- In other words, as functions are developed we'll stick writeups in here.
-
-
-
- CONVENTIONS
- -----------
-
- 1. All user-callable functions start with "Ctdl".
-
- 2. The functions starting with "CtdlInternal" are only to be used by other
-API functions. They are implemented mainly to consolidate the common code
-used by similar API functions, and make their implementation simple and
-straightforward.
-
-
-
- WRITING A SERVER-SIDE APPLICATION
- ---------------------------------
-
- Server-side applications written to the CitadelAPI may be written in any
-language, as long as the "citadelapi" library is linked in. Unlike normal
-user-mode programs, you must not declare a main() function, and there will be
-no stdin/stdout/stderr available. Instead, you must declare this:
-
- void CtdlMain() {
- /* your program's main loop goes here */
- }
-
- When a server-side application is started, the main() loop inside the
-CitadelAPI is invoked. This will perform all of the necessary initialization
-(attach to the server, authenticate, identify itself, etc.) and then call
-your program's CtdlMain() loop.
-
- By the time CtdlMain() receives control, there will be two public symbols
-you can access, which point to data structures containing various information
-that may be useful to the program:
-
- extern struct CtdlServerHandle CtdlAppHandle;
- extern struct CtdlServInfo CtdlAppServInfo;
-
- CtdlAppHandle contains various information about how and why this program is
-connected to the server. CtdlAppSrvInfo contains various static information
-about the server the program is connected to. Both CtdlServerHandle and
-CtdlServInfo are defined in the standard header files.
-
-
-
- ERROR HANDLING
- --------------
-
- int CtdlGetLastError()
-
- Returns the error code of a failed API call. The error codes used by the
-API are the same as those used by the Citadel session layer protocol, in order
-to facilitate a consistent development experience.
-
-
-
- INTERPROCESS COMMUNICATION FUNCTIONS
- ------------------------------------
-
- int CtdlSendExpressMessage(char *ToUser, char *MsgText)
-
- This function sends an express message (page) to the named user.
-
-
-
- USER ACCOUNT FUNCTIONS
- ----------------------
- The user account functions require administrative or privileged access. They
-return -1 in the event of an error.
-
-
-
- int CtdlGetUserPassword(char *buf, char *WhichUser)
- int CtdlSetUserPassword(char *buf, char *WhichUser)
-
- Get or set the password for a user account.
-
-
- unsigned int CtdlGetUserFlags(char *WhichUser)
- int CtdlSetUserFlags(unsigned int NewFlags, char *WhichUser)
-
- Get or set the various bits associated with a user account. Be careful with
-these flags; it is possible to corrupt a user account by handling them the
-wrong way. It is best to call CtdlGetUserFlags() to acquire the current set
-of flags, then twiddle the bits you're interested in, then call
-CtdlSetUserFlags() to write them back.
-
-
- int CtdlGetUserTimesCalled(char *WhichUser)
- int CtdlSetUserTimesCalled(unsigned int NewValue, char *WhichUser)
-
- Get or set the "number of times called" value for a user.
-
-
- int CtdlGetUserMessagesPosted(char *WhichUser)
- int CtdlSetUserMessagesPosted(unsigned int NewValue, char *WhichUser)
-
- Get or set the "number of messages posted" value for a user.
-
-
- int CtdlGetUserAccessLevel(char *WhichUser)
- int CtdlSetUserAccessLevel(unsigned int NewValue, char *WhichUser)
-
- Get or set a user's access level.
-
-
- long CtdlGetUserNumber(char *WhichUser)
- int CtdlSetUserNumber(long NewValue, char *WhichUser)
-
- Get or set the user number, In general there is never any reason to change
-a user's number. If for some reason you need to do this, be sure not to use
-a user number which already exists, or which has not yet been assigned.
-
-
- time_t CtdlGetUserLastCall(char *WhichUser)
- int CtdlSetUserLastCall(time_t NewValue, char *WhichUser)
-
- Get or set the timestamp of a user's last call.
-
-
- int CtdlForEachUser(int (*CallBack)(char *EachUser))
-
- This allows a user-supplied function to be called once for each user account
-on the system; the single argument passed to the function will be the name of
-the user being processed.
-
-
-
-
- ROOM FUNCTIONS
- --------------
-
- extern struct CtdlRoomInfo CtdlCurrentRoom;
-
- This structure contains information about the current room.
-
-
-
- int CtdlGotoRoom(char *RoomName)
-
- Goto any room to which the extension has access. An extension with
-administrative or privileged access may enter any room on the system. An
-extension running in the context of an ordinary user may enter any room to
-which the user has access.
-
-
- int CtdlForEachRoom(int (*CallBack)(char *EachRoom))
-
- This allows a user-supplied function to be called once for each active room
-on the system; the single argument passed to the function will be the name of
-the room being processed.
--- /dev/null
+Here's "take two" on the CitadelAPI extension library. These days it's not
+really a library at all, but rather a list of stuff that's inside the server that
+might be useful. Sort of. We'll see how it evolves.
+
+
+ USER RELATED FUNCTIONS
+ ----------------------
+
+ The fundamental user data is stored in "struct usersupp" which is defined
+in citadel.h. The following functions are available:
+
+
+ int getuser(struct usersupp *usbuf, char name[])
+
+ Given the name of a requested user and a buffer to store the usersupp
+record in, getuser() will search the userlog for the named user and load its
+data into the buffer. getuser() returns 0 upon success or a nonzero error
+code if the requested operation could not be performed.
+
+
+ void putuser(struct usersupp *usbuf, char *name)
+
+ After reading in a user record with getuser() and perhaps modifying the data
+in some way, a program may use putuser() to write it back to disk.
+
+
+ int lgetuser(struct usersupp *usbuf, char *name)
+ void lputuser(struct usersupp *usbuf, char *name)
+
+ If critical-section operation is required, this pair of calls may be used.
+They function the same as getuser() and putuser(), except that lgetuser()
+locks the user file immediately after retrieving the record and lputuser()
+unlocks it. This will guarantee that no other threads manipulate the same
+user record at the same time.
+
+ NOTE: do NOT attempt to combine the locking lgetuser/lputuser calls with any
+other locking calls in this API. Attempting to obtain concurrent locks on
+multiple files may result in a deadlock condition which would freeze the
+entire server.
+
+
+ void ForEachUser(void (*CallBack)(struct usersupp *EachUser))
+
+ This allows a user-supplied function to be called once for each user on
+the system. The user-supplied function will be called with a pointer to a
+usersupp structure as its only argument.
+
+
+ int getuserbynumber(struct usersupp *usbuf, long int number)
+
+ getuserbynumber() functions similarly to getuser(), except that it is
+supplied with a user number rather than a name. Calling this function
+results in a sequential search of the user file, so use it sparingly if at
+all.
+
+
+ int purge_user(char *pname)
+
+ This function deletes the named user off the system and erases all related
+objects: bio, photo, etc. It returns 0 upon success or a nonzero error code
+if the requested operation could not be performed.
+
+
#include "config.h"
-/*
- * hash() - hash table function for user lookup
- */
-int hash(char *str)
-{
- int h = 0;
- int i;
-
- for (i=0; i<strlen(str); ++i) h=h+((i+1)*tolower(str[i]));
- return(h);
- }
-
-
/*
* getuser() - retrieve named user into supplied buffer.
* returns 0 on success
if (getuser(&usbuf, pname) != 0) {
lprintf(5, "Cannot purge user <%s> - not found\n", pname);
- return(1);
+ return(ERROR+NO_SUCH_USER);
}
/* FIX Don't delete a user who is currently logged in. */
/*
- * List users
+ * Traverse the user file...
*/
-void cmd_list(void) {
+void ForEachUser(void (*CallBack)(struct usersupp *EachUser)) {
struct usersupp usbuf;
struct cdbdata *cdbus;
cdb_rewind(CDB_USERSUPP);
- cprintf("%d \n",LISTING_FOLLOWS);
while(cdbus = cdb_next_item(CDB_USERSUPP), cdbus != NULL) {
bzero(&usbuf, sizeof(struct usersupp));
( (cdbus->len > sizeof(struct usersupp)) ?
sizeof(struct usersupp) : cdbus->len) );
cdb_free(cdbus);
+ (*CallBack)(&usbuf);
+ }
+ }
+
- if (usbuf.axlevel > 0) {
+/*
+ * List one user (this works with cmd_list)
+ */
+void ListThisUser(struct usersupp *usbuf) {
+ if (usbuf->axlevel > 0) {
if ((CC->usersupp.axlevel>=6)
- ||((usbuf.flags&US_UNLISTED)==0)
+ ||((usbuf->flags&US_UNLISTED)==0)
||((CC->internal_pgm))) {
cprintf("%s|%d|%ld|%ld|%d|%d|",
- usbuf.fullname,
- usbuf.axlevel,
- usbuf.usernum,
- usbuf.lastcall,
- usbuf.timescalled,
- usbuf.posted);
- if (CC->usersupp.axlevel >= 6) cprintf("%s",usbuf.password);
+ usbuf->fullname,
+ usbuf->axlevel,
+ usbuf->usernum,
+ usbuf->lastcall,
+ usbuf->timescalled,
+ usbuf->posted);
+ if (CC->usersupp.axlevel >= 6)
+ cprintf("%s",usbuf->password);
cprintf("\n");
}
- }
}
+ }
+
+/*
+ * List users
+ */
+void cmd_list(void) {
+ cprintf("%d \n",LISTING_FOLLOWS);
+ ForEachUser(ListThisUser);
cprintf("000\n");
}
+
/*
* enter registration info
*/