citserver: citserver.o user_ops.o support.o room_ops.o file_ops.o \
msgbase.o config.o sysdep.o locate_host.o serv_chat.o \
- hooks.o housekeeping.o database.o control.o logging.o \
- serverapi.o
+ hooks.o housekeeping.o database.o control.o logging.o
$(CC) $(CFLAGS) citserver.o user_ops.o room_ops.o file_ops.o support.o \
msgbase.o config.o sysdep.o locate_host.o serv_chat.o \
hooks.o housekeeping.o database.o control.o logging.o \
- serverapi.o \
$(LFLAGS) $(SERVER_LFLAGS) -o citserver
citserver.o: citserver.c citadel.h
logging.o: logging.c citadel.h
$(CC) $(CFLAGS) -D_REENTRANT -c logging.c
-serverapi.o: serverapi.c citadel.h
- $(CC) $(CFLAGS) -D_REENTRANT -c serverapi.c
-
config.o: config.c config_decls.h citadel.h axdefs.h
$(CC) -O $(CFLAGS) -D_REENTRANT -c config.c
#include <ctype.h>
#include <string.h>
#include <errno.h>
-#include <pthread.h>
#include "citadel.h"
-#include "server.h"
-#include "proto.h"
-int CtdlGetLastError() {
- return(CC->CtdlErrno);
+struct CtdlServerHandle {
+ char ServerAddress[64];
+ int ServerPort;
+ char ipgmSecret[32];
+ char UserName[32];
+ char Password[32];
+ char InitialRoom[32];
+ int AssocClientSession;
+ };
+
+struct CtdlServerHandle CtdlMyHandle;
+
+
+void logoff(exitcode) {
+ exit(exitcode);
}
-int CtdlInternalGetUser(char *UserName, struct usersupp *usbuf) {
- if ( (strlen(UserName)==0) || (!strcasecmp(UserName,CC->curr_user)) ) {
- if (!CC->logged_in) {
- CC->CtdlErrno = ERROR+NOT_LOGGED_IN;
- return(-1);
- }
- memcpy(usbuf, &CC->usersupp, sizeof(struct usersupp));
- return(0);
- }
- else {
- if (getuser(usbuf, UserName) != 0) {
- CC->CtdlErrno = ERROR+NO_SUCH_USER;
- return(-1);
- }
- else {
- CC->CtdlErrno = 0;
- return(0);
- }
+/*
+ * 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
+ *
+ */
+
+main(argc, argv)
+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
+ * CtdlMyHandle to sane default values
+ */
+ bzero(&CtdlMyHandle, sizeof(struct CtdlServerHandle));
+
+ /* Now parse the command-line arguments fed to us by the server */
+ for (a=0; a<argc; ++a) switch(a) {
+ case 1: strcpy(CtdlMyHandle.ServerAddress, argv[a]);
+ break;
+ case 2: CtdlMyHandle.ServerPort = atoi(argv[a]);
+ break;
+ case 3: strcpy(CtdlMyHandle.ipgmSecret, argv[a]);
+ break;
+ case 4: strcpy(CtdlMyHandle.UserName, argv[a]);
+ break;
+ case 5: strcpy(CtdlMyHandle.Password, argv[a]);
+ break;
+ case 6: strcpy(CtdlMyHandle.InitialRoom, argv[a]);
+ break;
+ case 7: CtdlMyHandle.AssocClientSession = atoi(argv[a]);
+ break;
}
- }
-int CtdlGetUserAccessLevel(char *UserName) {
- struct usersupp usbuf;
+ /* Connect to the server */
+ argc = 3;
+ attach_to_server(argc, argv);
+ serv_gets(buf);
+ if (buf[0] != '2') exit(1);
- return( (CtdlInternalGetUser(UserName, &usbuf)==0)
- ? usbuf.axlevel
- : (-1)
- );
- }
+ /* Set up the server environment to our liking */
-long CtdlGetUserNumber(char *UserName) {
- struct usersupp usbuf;
+ sprintf(buf, "IDEN 0|5|006|CitadelAPI Client");
+ serv_puts(buf);
+ serv_gets(buf);
- return( (CtdlInternalGetUser(UserName, &usbuf)==0)
- ? usbuf.usernum
- : (-1L)
- );
- }
+ if (strlen(CtdlMyHandle.ipgmSecret) > 0) {
+ sprintf(buf, "IPGM %s", CtdlMyHandle.ipgmSecret);
+ serv_puts(buf);
+ serv_gets(buf);
+ }
+
+ if (strlen(CtdlMyHandle.UserName) > 0) {
+ sprintf(buf, "USER %s", CtdlMyHandle.UserName);
+ serv_puts(buf);
+ serv_gets(buf);
+ sprintf(buf, "PASS %s", CtdlMyHandle.Password);
+ serv_puts(buf);
+ serv_gets(buf);
+ }
+
+ sprintf(buf, "GOTO %s", CtdlMyHandle.InitialRoom);
+ serv_puts(buf);
+ serv_gets(buf);
+ if (buf[0] != '2') {
+ serv_puts("GOTO _BASEROOM_");
+ serv_gets(buf);
+ }
-time_t CtdlGetUserLastCall(char *UserName) {
- struct usersupp usbuf;
+ /* Now do the loop. */
+ sleep(10);
- return( (CtdlInternalGetUser(UserName, &usbuf)==0)
- ? usbuf.lastcall
- : (-1L)
- );
+ /* Clean up gracefully and exit. */
+ serv_puts("QUIT");
+ exit(0);
}
-> Please contact Art Cancro <ajc@uncnsrd.mt-kisco.ny.us> and obtain a unique
server type code, which can be assigned to your server program.
-> If you document what you did in detail, perhaps it can be added to a
-future release of the Citadel/UX program, so everyone can enjoy it.
+future release of the Citadel/UX program, so everyone can enjoy it. Better
+yet, just work with the Citadel development team on the main source tree.
If everyone follows this scheme, we can avoid a chaotic situation with lots
of confusion about which client program works with which server, etc. Client