/* Copyright (C) 1991, Marcus J. Ranum. All rights reserved. */ /* code to interface client MUDs with rwho server this is a standalone library. */ #include "config.h" #ifndef WIN32 # include <fcntl.h> # include <sys/file.h> # include <sys/types.h> # include <sys/socket.h> # include <netinet/in.h> # include <netdb.h> #endif #define DGRAMPORT 6888 #ifndef NO_HUGE_RESOLVER_CODE # ifndef WIN32 extern struct hostent *gethostbyname(const char *); # endif #endif static int dgramfd = -1; static char *password; static char *localnam; static char *lcomment; static struct sockaddr_in addr; time_t senttime; typedef struct sockaddr *SOCKADDRPTR; unsigned long int rwho_inet_addr(const char *cp) { int ip1, ip2, ip3, ip4; ip1 = ip2 = ip3 = ip4 = -1; sscanf(cp, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4); if (ip1 < 0 || ip2 < 0 || ip3 < 0 || ip4 < 0) return -1L; if (ip1 > 255 || ip2 > 255 || ip3 > 255 || ip4 > 255) return -1L; return htonl((ip1 << 24) | (ip2 << 16) | (ip3 << 8) | ip4); } /* enable RWHO and send the server a "we are up" message */ int rwhocli_setup(const char *server, const char *serverpw, const char *myname, const char *comment) { #ifndef NO_HUGE_RESOLVER_CODE struct hostent *hp; #endif char pbuf[512]; const char *p; if (dgramfd != -1) return (1); password = (char *) malloc(strlen(serverpw) + 1); localnam = (char *) malloc(strlen(myname) + 1); lcomment = (char *) malloc(strlen(comment) + 1); if (password == (char *) 0 || localnam == (char *) 0 || lcomment == (char *) 0) return (1); strcpy(password, serverpw); strcpy(localnam, myname); strcpy(lcomment, comment); p = server; while (*p != '\0' && (*p == '.' || isdigit(*p))) p++; if (*p != '\0') { #ifndef NO_HUGE_RESOLVER_CODE if ((hp = (struct hostent *) gethostbyname((char *) server)) == (struct hostent *) 0) return (1); (void) bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length); #else return (1); #endif } else { unsigned long f; if ((f = rwho_inet_addr(server)) == -1L) return (1); (void) bcopy((char *) &f, (char *) &addr.sin_addr, sizeof(f)); } addr.sin_port = htons(DGRAMPORT); addr.sin_family = AF_INET; if ((dgramfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return (1); time(&senttime); snprintf(pbuf, sizeof(pbuf), "U\t%.20s\t%.20s\t%.20s\t%.10ld\t0\t%.25s", localnam, password, localnam, senttime, comment); sendto(dgramfd, pbuf, strlen(pbuf), 0, (SOCKADDRPTR) & addr, sizeof(addr)); return (0); } /* disable RWHO */ int rwhocli_shutdown(void) { char pbuf[512]; if (dgramfd != -1) { snprintf(pbuf, sizeof(pbuf), "D\t%.20s\t%.20s\t%.20s", localnam, password, localnam); sendto(dgramfd, pbuf, strlen(pbuf), 0, (SOCKADDRPTR) & addr, sizeof(addr)); close(dgramfd); dgramfd = -1; free(password); free(localnam); } return (0); } /* send an update ping that we're alive */ int rwhocli_pingalive(void) { char pbuf[512]; if (dgramfd != -1) { snprintf(pbuf, sizeof(pbuf), "M\t%.20s\t%.20s\t%.20s\t%.10ld\t0\t%.25s", localnam, password, localnam, senttime, lcomment); sendto(dgramfd, pbuf, strlen(pbuf), 0, (SOCKADDRPTR) & addr, sizeof(addr)); } return (0); } /* send a "so-and-so-logged in" message */ int rwhocli_userlogin(const char *uid, const char *name, time_t tim) { char pbuf[512]; if (dgramfd != -1) { snprintf(pbuf, sizeof(pbuf), "A\t%.20s\t%.20s\t%.20s\t%.20s\t%.10ld\t0\t%.20s", localnam, password, localnam, uid, tim, name); sendto(dgramfd, pbuf, strlen(pbuf), 0, (SOCKADDRPTR) & addr, sizeof(addr)); } return (0); } /* send a "so-and-so-logged out" message */ int rwhocli_userlogout(const char *uid) { char pbuf[512]; if (dgramfd != -1) { snprintf(pbuf, sizeof(pbuf), "Z\t%.20s\t%.20s\t%.20s\t%.20s", localnam, password, localnam, uid); sendto(dgramfd, pbuf, strlen(pbuf), 0, (SOCKADDRPTR) & addr, sizeof(addr)); } return (0); }