* Implemented a bunch of user account related functions in the
authorArt Cancro <ajc@citadel.org>
Tue, 18 Aug 1998 03:53:02 +0000 (03:53 +0000)
committerArt Cancro <ajc@citadel.org>
Tue, 18 Aug 1998 03:53:02 +0000 (03:53 +0000)
          CitadelAPI library.

citadel/ChangeLog
citadel/citadelapi.c
citadel/ipcdef.h
citadel/techdoc/api.txt
citadel/user_ops.c

index 1fc3c5dd9c4c1bcb0283adf1649179ccaad4cc85..e1de90c51efcdacb39b2aa156283462267a6236d 100644 (file)
@@ -1,3 +1,7 @@
+Mon Aug 17 23:52:13 EDT 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
+       * Implemented a bunch of user account related functions in the
+         CitadelAPI library.
+
 Mon Aug 17 20:01:18 EDT 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
        * Fixed the crash problem.  It wasn't AGUP/ASUP, but rather a buffer
          overrun in getuser() (thanks, Nathan).  Implemented overrun checks
index 68bd7f5805ee06c6f081b65e82ed429629d7c3b6..4ada1e108dde2f1099aa8d51b189639614e2b6a4 100644 (file)
@@ -7,6 +7,13 @@
 #include <errno.h>
 #include "citadel.h"
 
+
+struct CtdlInternalList {
+       struct CtdlInternalList *next;
+       char data[256];
+       };
+
+
 struct CtdlServerHandle CtdlAppHandle;
 struct CtdlServInfo CtdlAppServInfo;
 int CtdlErrno = 0;
@@ -17,6 +24,91 @@ void logoff(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()  -  CtdlInternalExtract 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()  -  CtdlInternalExtract 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:
@@ -135,3 +227,174 @@ int CtdlSendExpressMessage(char *ToUser, char *MsgText) {
        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(&params[a][0], &buf[4], a);
+               }
+       strcpy(&params[ParamNum][0], ParamBuf);
+       strcpy(buf, "ASUP ");
+       for (a=0; a<8; ++a) {
+               strcat(buf, &params[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 < 1) || (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);
+       }
index c7bbcc67edc02f5f7407097eb361b35b627b5107..808d2143a6c5e12e88c3d7ea68d62477684e9c05 100644 (file)
@@ -13,6 +13,7 @@
 
 #define INTERNAL_ERROR         10
 #define TOO_BIG                        11
+#define ILLEGAL_VALUE          12
 #define NOT_LOGGED_IN          20
 #define CMD_NOT_SUPPORTED      30
 #define PASSWORD_REQUIRED      40
index 421c06f3d45710b4f0ba4b1fc2e78d241c2eca45..bde1492d868e9c0f69409ce4fdf60f8ea6514cd0 100644 (file)
@@ -68,3 +68,67 @@ to facilitate a consistent development experience.
  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.
+
index dcd3ddde7b443853641b5150b007536c89225ff0..725d41ab8c10b0bc92b190603be2a69f6546bd47 100644 (file)
@@ -139,7 +139,9 @@ int getuserbynumber(struct usersupp *usbuf, long int number)
 
        while(cdbus = cdb_next_item(CDB_USERSUPP), cdbus != NULL) {
                bzero(usbuf, sizeof(struct usersupp));
-               memcpy(usbuf, cdbus->ptr, cdbus->len);
+               memcpy(usbuf, cdbus->ptr,
+                       ( (cdbus->len > sizeof(struct usersupp)) ?
+                       sizeof(struct usersupp) : cdbus->len) );
                cdb_free(cdbus);
                if (usbuf->usernum == number) {
                        return(0);
@@ -717,7 +719,9 @@ void cmd_gnur(void) {
        cdb_rewind(CDB_USERSUPP);
        while (cdbus = cdb_next_item(CDB_USERSUPP), cdbus != NULL) {
                bzero(&usbuf, sizeof(struct usersupp));
-               memcpy(&usbuf, cdbus->ptr, cdbus->len);
+               memcpy(&usbuf, cdbus->ptr,
+                       ( (cdbus->len > sizeof(struct usersupp)) ?
+                       sizeof(struct usersupp) : cdbus->len) );
                cdb_free(cdbus);
                if ((usbuf.flags & US_NEEDVALID)
                   &&(usbuf.axlevel > 0)) {
@@ -859,7 +863,9 @@ void cmd_list(void) {
 
        while(cdbus = cdb_next_item(CDB_USERSUPP), cdbus != NULL) {
                bzero(&usbuf, sizeof(struct usersupp));
-               memcpy(&usbuf, cdbus->ptr, cdbus->len);
+               memcpy(&usbuf, cdbus->ptr,
+                       ( (cdbus->len > sizeof(struct usersupp)) ?
+                       sizeof(struct usersupp) : cdbus->len) );
                cdb_free(cdbus);
 
            if (usbuf.axlevel > 0) {