Subject: libident ported to 2.11BSD (#359) Index: usr.lib/libident 2.11BSD Description: The IDENT client library has been ported to 2.11BSD. Libident is a collection of routines which applications use to communicate with and parse the responses from identd processes. Repeat-By: Since this is a new library being added this section doesn't apply. Fix: 'libident-0.20' required only a couple minor reorderings of #include statements in order to compile under 2.11BSD. A Makefile in the 2.11BSD style was created. No other changes were required. Cut where indicated, saving to a file (/tmp/359) and then: cd /tmp sh 359 patch -p0 < 359.patch cd /usr/src/usr.lib/libident make make install make clean As always this and previous updates to 2.11BSD are available via anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the directory /pub/2.11BSD. ------------------------cut here------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # /tmp/359.patch # /usr/src/usr.lib/libident # This archive created: Wed Dec 18 20:30:29 1996 export PATH; PATH=/bin:/usr/bin:$PATH if test -f '/tmp/359.patch' then echo shar: "will not over-write existing file '/tmp/359.patch'" else cat << \SHAR_EOF > '/tmp/359.patch' *** /usr/src/usr.lib/Makefile.old Sat Oct 26 12:14:15 1996 --- /usr/src/usr.lib/Makefile Fri Dec 13 20:09:03 1996 *************** *** 3,9 **** # All rights reserved. The Berkeley software License Agreement # specifies the terms and conditions for redistribution. # ! # @(#)Makefile 5.12.2 (2.11BSD GTE) 1996/10/24 # DESTDIR= CFLAGS= -O --- 3,9 ---- # All rights reserved. The Berkeley software License Agreement # specifies the terms and conditions for redistribution. # ! # @(#)Makefile 5.12.3 (2.11BSD GTE) 1996/12/13 # DESTDIR= CFLAGS= -O *************** *** 12,18 **** # Subdirectories whose routines are included in the making of the # master tags file (/usr/lib/tags); the Fortran libraries should ! # be on this list, but we don't control them.... # TAGSDIR=libcurses libdbm libln libm libmp libpc libtermlib libutil libvmf \ liberrlst --- 12,18 ---- # Subdirectories whose routines are included in the making of the # master tags file (/usr/lib/tags); the Fortran libraries should ! # be on this list. # TAGSDIR=libcurses libdbm libln libm libmp libpc libtermlib libutil libvmf \ liberrlst *************** *** 24,30 **** # SUBDIR= lib2648 libF77 libI77 libU77 libcurses libdbm libln \ libom libmp libplot libtermlib liby libutil libvmf \ ! liberrlst libstubs # Shell scripts that need only be installed and are never removed. # --- 24,30 ---- # SUBDIR= lib2648 libF77 libI77 libU77 libcurses libdbm libln \ libom libmp libplot libtermlib liby libutil libvmf \ ! liberrlst libident libstubs # Shell scripts that need only be installed and are never removed. # *** /VERSION.old Wed Dec 18 19:49:44 1996 --- /VERSION Wed Dec 18 20:29:17 1996 *************** *** 1,4 **** ! Current Patch Level: 358 2.11 BSD ============ --- 1,4 ---- ! Current Patch Level: 359 2.11 BSD ============ SHAR_EOF chmod 755 '/tmp/359.patch' fi if test ! -d '/usr/src/usr.lib/libident' then mkdir '/usr/src/usr.lib/libident' fi cd '/usr/src/usr.lib/libident' if test -f 'ident.h' then echo shar: "will not over-write existing file 'ident.h'" else cat << \SHAR_EOF > 'ident.h' /* ** ident.h ** ** Author: Peter Eriksson ** Intruder: Pdr Emanuelsson */ #ifndef __IDENT_H__ #define __IDENT_H__ #ifdef __cplusplus extern "C" { #endif /* Sigh */ #ifdef __STDC__ # if __STDC__ == 1 # define IS_STDC 1 # endif #endif #ifdef __P # undef __P #endif #ifdef IS_STDC # define __P(AL) AL #ifdef IN_LIBIDENT_SRC # define __P1(t1,a1) \ (t1 a1) # define __P2(t1,a1,t2,a2) \ (t1 a1, t2 a2) # define __P3(t1,a1,t2,a2,t3,a3) \ (t1 a1, t2 a2, t3 a3) # define __P4(t1,a1,t2,a2,t3,a3,t4,a4) \ (t1 a1, t2 a2, t3 a3, t4 a4) # define __P5(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) \ (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) # define __P7(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) \ (t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) #endif #else # define __P(AL) () #ifdef IN_LIBIDENT_SRC # define __P1(t1,a1) (a1) \ t1 a1; # define __P2(t1,a1,t2,a2) (a1, a2) \ t1 a1; \ t2 a2; # define __P3(t1,a1,t2,a2,t3,a3) (a1, a2, a3) \ t1 a1; \ t2 a2; \ t3 a3; # define __P4(t1,a1,t2,a2,t3,a3,t4,a4) (a1, a2, a3, a4) \ t1 a1; \ t2 a2; \ t3 a3; \ t4 a4; # define __P5(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5) (a1, a2, a3, a4, a5) \ t1 a1; \ t2 a2; \ t3 a3; \ t4 a4; \ t5 a5; # define __P7(t1,a1,t2,a2,t3,a3,t4,a4,t5,a5,t6,a6,t7,a7) \ (a1, a2, a3, a4, a5, a6, a7) \ t1 a1; \ t2 a2; \ t3 a3; \ t4 a4; \ t5 a5; \ t6 a6; \ t7 a7; #endif #endif #ifdef IS_STDC # undef IS_STDC #endif #ifdef _AIX # include #endif #ifdef __sgi # include #endif #include #include #include #if defined(VMS) && !defined(FD_SETSIZE) # define FD_SETSIZE 64 #endif /* * Sigh, GCC v2 complains when using undefined struct tags * in function prototypes... */ #if defined(__GNUC__) && !defined(INADDR_ANY) # define __STRUCT_IN_ADDR_P void * #else # define __STRUCT_IN_ADDR_P struct in_addr * #endif #if defined(__GNUC__) && !defined(DST_NONE) # define __STRUCT_TIMEVAL_P void * #else # define __STRUCT_TIMEVAL_P struct timeval * #endif #if defined(__sgi) && defined(_POSIX_SOURCE) # undef __STRUCT_TIMEVAL_P # define __STRUCT_TIMEVAL_P void * #endif #ifndef IDBUFSIZE # define IDBUFSIZE 2048 #endif #ifndef IDPORT # define IDPORT 113 #endif typedef struct { int fd; char buf[IDBUFSIZE]; } ident_t; typedef struct { int lport; /* Local port */ int fport; /* Far (remote) port */ char *identifier; /* Normally user name */ char *opsys; /* OS */ char *charset; /* Charset (what did you expect?) */ } IDENT; /* For higher-level routines */ /* Low-level calls and macros */ #define id_fileno(ID) ((ID)->fd) extern ident_t * id_open __P((__STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P faddr, __STRUCT_TIMEVAL_P timeout)); extern int id_close __P((ident_t *id)); extern int id_query __P((ident_t *id, int lport, int fport, __STRUCT_TIMEVAL_P timeout)); extern int id_parse __P((ident_t *id, __STRUCT_TIMEVAL_P timeout, int *lport, int *fport, char **identifier, char **opsys, char **charset)); /* High-level calls */ extern IDENT *ident_lookup __P((int fd, int timeout)); extern char *ident_id __P((int fd, int timeout)); extern IDENT *ident_query __P(( __STRUCT_IN_ADDR_P laddr, __STRUCT_IN_ADDR_P raddr, int lport, int rport, int timeout)); extern void ident_free __P((IDENT *id)); extern char id_version[]; #ifdef IN_LIBIDENT_SRC extern char *id_strdup __P((char *str)); extern char *id_strtok __P((char *cp, char *cs, char *dc)); #endif #ifdef __cplusplus } #endif #endif SHAR_EOF chmod 644 'ident.h' fi if test -f 'README' then echo shar: "will not over-write existing file 'README'" else cat << \SHAR_EOF > 'README' COPYRIGHT ISSUES: This version of 'libident' is hereby released into the Public Domain. It may be distributed for a fee or without a fee. We only ask you not to pretend you wrote it. If you make any changes, please send sources or a diff of it to us (pen@lysator.liu.se or pell@lysator.liu.se), so we can keep _one_ unified version of libident available... COMMENTS: This is the second stab at a small library to interface to the Ident protocol server. Maybe this will work correctly on some machines.. :-) The ident-tester.c file is a small daemon (to be started from Inetd) that does an ident lookup on you if you telnet into it. Can be used to verify that your Ident server is working correctly. I'm currently running this "ident-tester" on port 114 at lysator.liu.se (130.236.254.1) if you wish to test your server. /Peter Eriksson , 1 Aug 1992 This library now contains some higher-level routines, as well as a similar test program to test these (lookup-tester). /Pdr Emanuelsson , 4 April 1993 Support for NextStep 3.1 added. /Michael Kuch , 13 Aug 1993 Updated the ident.h header file to work with Linux, and reorganized the Makefile for easier compilation... /Peter Eriksson, 18 Oct 1994 Added the copyright notice at the top. /Peter Eriksson, 29 Nov 1994 For release 0.18: Added some bug fixes and improvements from Jean-Philippe Martin-Flatin (syj@ecmwf.int). /Peter Eriksson, 5 Oct 1995 For release 0.20: Some cleanup of the distribution, and some bug fixes in the ident-tester.c source. Perhaps it should be called 1.0? (Perhaps it should use GNU Autoconf...) /Peter Eriksson, 13 Nov 1996 SHAR_EOF chmod 644 'README' fi if test -f 'id_parse.c' then echo shar: "will not over-write existing file 'id_parse.c'" else cat << \SHAR_EOF > 'id_parse.c' /* ** id_parse.c Receive and parse a reply from an IDENT server ** ** Author: Peter Eriksson ** Fiddling: Pdr Emanuelsson */ #ifdef NeXT3 # include #endif #include #include #include #include #ifdef HAVE_ANSIHEADERS # include # include # include #endif #include #include #include #ifdef _AIX # include #endif #ifdef _AIX # include #endif #ifdef VMS # include /* for fd_set */ #endif #define IN_LIBIDENT_SRC #include "ident.h" int id_parse __P7(ident_t *, id, struct timeval *, timeout, int *, lport, int *, fport, char **, identifier, char **, opsys, char **, charset) { char c, *cp, *tmp_charset; fd_set rs; int pos, res=0, lp, fp; errno = 0; tmp_charset = 0; if (!id) return -1; if (lport) *lport = 0; if (fport) *fport = 0; if (identifier) *identifier = 0; if (opsys) *opsys = 0; if (charset) *charset = 0; pos = strlen(id->buf); if (timeout) { FD_ZERO(&rs); FD_SET(id->fd, &rs); #ifdef __hpux if ((res = select(FD_SETSIZE, (int *) &rs, (int *)0, (int *)0, timeout)) < 0) #else if ((res = select(FD_SETSIZE, &rs, (fd_set *)0, (fd_set *)0, timeout)) < 0) #endif return -1; if (res == 0) { errno = ETIMEDOUT; return -1; } } /* Every octal value is allowed except 0, \n and \r */ while (pos < sizeof(id->buf) && (res = read(id->fd, id->buf + pos, 1)) == 1 && id->buf[pos] != '\n' && id->buf[pos] != '\r') pos++; if (res < 0) return -1; if (res == 0) { errno = ENOTCONN; return -1; } if (id->buf[pos] != '\n' && id->buf[pos] != '\r') return 0; /* Not properly terminated string */ id->buf[pos++] = '\0'; /* ** Get first field ( , ) */ cp = id_strtok(id->buf, ":", &c); if (!cp) return -2; if (sscanf(cp, " %d , %d", &lp, &fp) != 2) { if (identifier) { *identifier = id_strdup(cp); if (*identifier == NULL) return -4; } return -2; } if (lport) *lport = lp; if (fport) *fport = fp; /* ** Get second field (USERID or ERROR) */ cp = id_strtok((char *)0, ":", &c); if (!cp) return -2; if (strcmp(cp, "ERROR") == 0) { cp = id_strtok((char *)0, "\n\r", &c); if (!cp) return -2; if (identifier) { *identifier = id_strdup(cp); if (*identifier == NULL) return -4; } return 2; } else if (strcmp(cp, "USERID") == 0) { /* ** Get first subfield of third field */ cp = id_strtok((char *) 0, ",:", &c); if (!cp) return -2; if (opsys) { *opsys = id_strdup(cp); if (*opsys == NULL) return -4; } /* ** We have a second subfield () */ if (c == ',') { cp = id_strtok((char *)0, ":", &c); if (!cp) return -2; tmp_charset = cp; if (charset) { *charset = id_strdup(cp); if (*charset == NULL) return -4; } /* ** We have even more subfields - ignore them */ if (c == ',') id_strtok((char *)0, ":", &c); } if (tmp_charset && strcmp(tmp_charset, "OCTET") == 0) cp = id_strtok((char *)0, (char *)0, &c); else cp = id_strtok((char *)0, "\n\r", &c); if (identifier) { *identifier = id_strdup(cp); if (*identifier == NULL) return -4; } return 1; } else { if (identifier) { *identifier = id_strdup(cp); if (*identifier == NULL) return -4; } return -3; } } SHAR_EOF chmod 644 'id_parse.c' fi if test -f 'id_open.c' then echo shar: "will not over-write existing file 'id_open.c'" else cat << \SHAR_EOF > 'id_open.c' /* ** id_open.c Establish/initiate a connection to an IDENT server ** ** Author: Peter Eriksson ** Fixes: Pdr Emanuelsson */ #ifdef NeXT3 # include #endif #include #include #include #ifdef HAVE_ANSIHEADERS # include # include # include # if !defined(__sgi) && !defined(VMS) # define bzero(p,l) memset(p, 0, l) # endif #endif #include #include #include #include #include #define IN_LIBIDENT_SRC #include "ident.h" #include #ifdef _AIX # include #endif ident_t *id_open __P3(struct in_addr *, laddr, struct in_addr *, faddr, struct timeval *, timeout) { ident_t *id; int res, tmperrno; struct sockaddr_in sin_laddr, sin_faddr; fd_set rs, ws, es; #ifndef OLD_SETSOCKOPT int on = 1; struct linger linger; #endif if ((id = (ident_t *) malloc(sizeof(*id))) == 0) return 0; if ((id->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { free(id); return 0; } if (timeout) { if ((res = fcntl(id->fd, F_GETFL, 0)) < 0) goto ERROR; #ifndef VMS if (fcntl(id->fd, F_SETFL, res | FNDELAY) < 0) goto ERROR; #endif } /* We silently ignore errors if we can't change LINGER */ #ifdef OLD_SETSOCKOPT /* Old style setsockopt() */ (void) setsockopt(id->fd, SOL_SOCKET, SO_DONTLINGER); (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR); #else /* New style setsockopt() */ linger.l_onoff = 0; linger.l_linger = 0; (void) setsockopt(id->fd, SOL_SOCKET, SO_LINGER, (void *) &linger, sizeof(linger)); (void) setsockopt(id->fd, SOL_SOCKET, SO_REUSEADDR, (void *) &on, sizeof(on)); #endif id->buf[0] = '\0'; bzero((char *)&sin_laddr, sizeof(sin_laddr)); sin_laddr.sin_family = AF_INET; sin_laddr.sin_addr = *laddr; sin_laddr.sin_port = 0; if (bind(id->fd, (struct sockaddr *) &sin_laddr, sizeof(sin_laddr)) < 0) { #ifdef DEBUG perror("libident: bind"); #endif goto ERROR; } bzero((char *)&sin_faddr, sizeof(sin_faddr)); sin_faddr.sin_family = AF_INET; sin_faddr.sin_addr = *faddr; sin_faddr.sin_port = htons(IDPORT); errno = 0; res = connect(id->fd, (struct sockaddr *) &sin_faddr, sizeof(sin_faddr)); if (res < 0 && errno != EINPROGRESS) { #ifdef DEBUG perror("libident: connect"); #endif goto ERROR; } if (timeout) { FD_ZERO(&rs); FD_ZERO(&ws); FD_ZERO(&es); FD_SET(id->fd, &rs); FD_SET(id->fd, &ws); FD_SET(id->fd, &es); #ifdef __hpux if ((res = select(FD_SETSIZE, (int *) &rs, (int *) &ws, (int *) &es, timeout)) < 0) #else if ((res = select(FD_SETSIZE, &rs, &ws, &es, timeout)) < 0) #endif { #ifdef DEBUG perror("libident: select"); #endif goto ERROR; } if (res == 0) { errno = ETIMEDOUT; goto ERROR; } if (FD_ISSET(id->fd, &es)) goto ERROR; if (!FD_ISSET(id->fd, &rs) && !FD_ISSET(id->fd, &ws)) goto ERROR; } return id; ERROR: tmperrno = errno; /* Save, so close() won't erase it */ close(id->fd); free(id); errno = tmperrno; return 0; } SHAR_EOF chmod 644 'id_open.c' fi if test -f 'id_close.c' then echo shar: "will not over-write existing file 'id_close.c'" else cat << \SHAR_EOF > 'id_close.c' /* ** id_close.c Close a connection to an IDENT server ** ** Author: Peter Eriksson */ #ifdef NeXT3 # include #endif #ifdef HAVE_ANSIHEADERS # include # include #endif #define IN_LIBIDENT_SRC #include "ident.h" int id_close __P1(ident_t *, id) { int res; res = close(id->fd); free(id); return res; } SHAR_EOF chmod 644 'id_close.c' fi if test -f 'id_query.c' then echo shar: "will not over-write existing file 'id_query.c'" else cat << \SHAR_EOF > 'id_query.c' /* ** id_query.c Transmit a query to an IDENT server ** ** Author: Peter Eriksson */ #ifdef NeXT3 # include #endif #include #include #include #ifdef HAVE_ANSIHEADERS # include # include # include #endif #include #include #include #ifdef _AIX # include #endif #ifdef _AIX # include #endif #ifdef VMS # include /* for fd_set */ #endif #define IN_LIBIDENT_SRC #include "ident.h" int id_query __P4(ident_t *, id, int, lport, int, fport, struct timeval *, timeout) { #ifdef SIGRETURNTYPE SIGRETURNTYPE (*old_sig)(); #else void (*old_sig) __P((int)); #endif int res; char buf[80]; fd_set ws; sprintf(buf, "%d , %d\r\n", lport, fport); if (timeout) { FD_ZERO(&ws); FD_SET(id->fd, &ws); #ifdef __hpux if ((res = select(FD_SETSIZE, (int *)0, (int *)&ws, (int *)0, timeout)) < 0) #else if ((res = select(FD_SETSIZE, (fd_set *)0, &ws, (fd_set *)0, timeout)) < 0) #endif return -1; if (res == 0) { errno = ETIMEDOUT; return -1; } } old_sig = signal(SIGPIPE, SIG_IGN); res = write(id->fd, buf, strlen(buf)); signal(SIGPIPE, old_sig); return res; } SHAR_EOF chmod 644 'id_query.c' fi if test -f 'Makefile' then echo shar: "will not over-write existing file 'Makefile'" else cat << \SHAR_EOF > 'Makefile' # # Place in the public domain 1996/12/13 - sms. # # @(#)Makefile 1.0 (2.11BSD) 1996/12/13 # DESTDIR= LIBDIR=$(DESTDIR)/usr/lib INCDIR=$(DESTDIR)/usr/include MANDIR=$(DESTDIR)/usr/man/cat3 CFLAGS=-O -DSIGRETURNTYPE=int -DHAVE_ANSIHEADERS LFLAGS=-i LIB= libident.a SRCS = ident.c id_open.c id_close.c id_query.c id_parse.c support.c version.c OBJS = ident.o id_open.o id_close.o id_query.o id_parse.o support.o version.o .c.o: @${CC} -p ${CFLAGS} -c $*.c @-ld -X -o profiled/$*.o -r $*.o ${CC} ${CFLAGS} -c $*.c @-ld -x -r $*.o @mv a.out $*.o all: libident.a libident_p.a lookup-tester ident-tester ident.0 libident.a libident_p.a: $(OBJS) @echo building normal libident @ar ru libident.a ${OBJS} ranlib libident.a @echo building profiled libident @cd profiled; ar ru ../libident_p.a ${OBJS} ranlib libident_p.a ident-tester: libident.a ident-tester.o ${CC} $(CFLAGS) ${LFLAGS} -o ident-tester ident-tester.o $(LIB) lookup-tester: libident.a lookup-tester.o ${CC} $(CFLAGS) ${LFLAGS} -o lookup-tester lookup-tester.o $(LIB) ident.0: ident.3 /usr/man/manroff ident.3 > ident.0 install: all install -c -m 644 libident.a $(LIBDIR)/libident.a install -c -m 644 libident_p.a $(LIBDIR)/libident_p.a ranlib $(LIBDIR)/libident.a $(LIBDIR)/libident_p.a install -c -m 444 ident.h $(INCDIR)/ident.h install -c -m 444 ident.0 $(MANDIR)/ident.0 clean: -rm -f libident.a libident_p.a ident-tester lookup-tester *.o ident.0 -rm -f profiled/*.o depend: mkdep ${CFLAGS} ${SRCS} SHAR_EOF chmod 644 'Makefile' fi if test -f 'ident-tester.c' then echo shar: "will not over-write existing file 'ident-tester.c'" else cat << \SHAR_EOF > 'ident-tester.c' /* ** ident-tester.c A small daemon that can be used to test Ident ** servers ** ** Author: Peter Eriksson , 10 Aug 1992 */ #ifdef NeXT3 # include #endif #include #include #include #include #ifdef HAVE_ANSIHEADERS # include # include #endif #include #include #define IN_LIBIDENT_SRC #include "ident.h" #include /* ** Return the name of the connecting host, or the IP number as a string. */ char *gethost __P1(struct in_addr *, addr) { struct hostent *hp; hp = gethostbyaddr((char *) addr, sizeof(struct in_addr), AF_INET); if (hp) return (char *) hp->h_name; else return inet_ntoa(*addr); } void main __P2(int, argc, char **, argv) { struct sockaddr_in laddr, faddr; int len, res, lport, fport; ident_t *id; char *identifier, *opsys, *charset; puts("Welcome to the IDENT server tester, version 1.9\r\n"); printf("(Linked with libident-%s)\r\n\n", id_version); fflush(stdout); len = sizeof(faddr); getpeername(0, (struct sockaddr *) &faddr, &len); len = sizeof(laddr); getsockname(0, (struct sockaddr *) &laddr, &len); printf("Connecting to Ident server at %s...\r\n", inet_ntoa(faddr.sin_addr)); fflush(stdout); #ifdef LOG_LOCAL3 openlog("tidentd", 0, LOG_LOCAL3); #else openlog("tidentd", 0); #endif id = id_open(&laddr.sin_addr, &faddr.sin_addr, NULL); if (!id) { if (errno) { int saved_errno = errno; char *hs; perror("Connection denied"); fflush(stderr); hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Error: id_open(): host=%s, error=%m", hs); } else puts("Connection denied."); exit(0); } printf("Querying for lport %d, fport %d....\r\n", (int) ntohs(faddr.sin_port), (int) ntohs(laddr.sin_port)); fflush(stdout); errno = 0; if (id_query(id, ntohs(faddr.sin_port), ntohs(laddr.sin_port), 0) < 0) { if (errno) { int saved_errno = errno; char *hs; perror("id_query()"); fflush(stderr); hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Error: id_query(): host=%s, error=%m", hs); } else { puts("Query failed.\n"); } exit(0); } printf("Reading response data...\r\n"); fflush(stdout); res = id_parse(id, NULL, &lport, &fport, &identifier, &opsys, &charset); switch (res) { default: if (errno) { int saved_errno = errno; char *hs; perror("id_parse()"); hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Error: id_parse(): host=%s, error=%m", hs); } else puts("Error: Invalid response (empty response?).\n"); break; case -2: { int saved_errno = errno; char *hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Error: id_parse(): host=%s, Parse Error: %s", hs, identifier ? identifier : ""); if (identifier) printf("Parse error on reply:\n \"%s\"\n", identifier); else printf("Unidentifiable parse error on reply.\n"); } break; case -3: { int saved_errno = errno; char *hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Error: id_parse(): host=%s, Illegal reply type: %s", hs, identifier); printf("Parse error in reply: Illegal reply type: %s\n", identifier); } break; case 0: { int saved_errno = errno; char *hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Error: id_parse(): host=%s, NotReady", hs); puts("Not ready. This should not happen...\r"); } break; case 2: { int saved_errno = errno; char *hs = gethost(&faddr.sin_addr); errno = saved_errno; syslog(LOG_DEBUG, "Reply: Error: host=%s, error=%s", hs, identifier); } printf("Error response is:\r\n"); printf(" Lport........ %d\r\n", lport); printf(" Fport........ %d\r\n", fport); printf(" Error........ %s\r\n", identifier); break; case 1: if (charset) syslog(LOG_INFO, "Reply: Userid: host=%s, opsys=%s, charset=%s, userid=%s", gethost(&faddr.sin_addr), opsys, charset, identifier); else syslog(LOG_INFO, "Reply: Userid: host=%s, opsys=%s, userid=%s", gethost(&faddr.sin_addr), opsys, identifier); printf("Userid response is:\r\n"); printf(" Lport........ %d\r\n", lport); printf(" Fport........ %d\r\n", fport); printf(" Opsys........ %s\r\n", opsys); printf(" Charset...... %s\r\n", charset ? charset : ""); printf(" Identifier... %s\r\n", identifier); if (id_query(id, ntohs(faddr.sin_port), ntohs(laddr.sin_port), 0) >= 0) { if (id_parse(id, NULL, &lport, &fport, &identifier, &opsys, &charset) == 1) printf(" Multiquery... Enabled\r\n"); } } fflush(stdout); sleep(1); exit(0); } SHAR_EOF chmod 644 'ident-tester.c' fi if test -f 'ident.c' then echo shar: "will not over-write existing file 'ident.c'" else cat << \SHAR_EOF > 'ident.c' /* ** ident.c High-level calls to the ident lib ** ** Author: Pdr Emanuelsson ** Hacked by: Peter Eriksson */ #ifdef NeXT3 # include #endif #include #ifdef HAVE_ANSIHEADERS # include # include #endif #include #include #include #define IN_LIBIDENT_SRC #include "ident.h" #include /* Do a complete ident query and return result */ IDENT *ident_lookup __P2(int, fd, int, timeout) { struct sockaddr_in localaddr, remoteaddr; int len; len = sizeof(remoteaddr); if (getpeername(fd, (struct sockaddr*) &remoteaddr, &len) < 0) return 0; len = sizeof(localaddr); if (getsockname(fd, (struct sockaddr *) &localaddr, &len) < 0) return 0; return ident_query( &localaddr.sin_addr, &remoteaddr.sin_addr, ntohs(localaddr.sin_port), ntohs(remoteaddr.sin_port), timeout); } IDENT *ident_query __P5(struct in_addr *, laddr, struct in_addr *, raddr, int, lport, int, rport, int, timeout) { int res; ident_t *id; struct timeval timout; IDENT *ident=0; timout.tv_sec = timeout; timout.tv_usec = 0; if (timeout) id = id_open( laddr, raddr, &timout); else id = id_open( laddr, raddr, (struct timeval *)0); if (!id) { errno = EINVAL; return 0; } if (timeout) res = id_query(id, rport, lport, &timout); else res = id_query(id, rport, lport, (struct timeval *) 0); if (res < 0) { id_close(id); return 0; } ident = (IDENT *) malloc(sizeof(IDENT)); if (!ident) { id_close(id); return 0; } if (timeout) res = id_parse(id, &timout, &ident->lport, &ident->fport, &ident->identifier, &ident->opsys, &ident->charset); else res = id_parse(id, (struct timeval *) 0, &ident->lport, &ident->fport, &ident->identifier, &ident->opsys, &ident->charset); if (res != 1) { free(ident); id_close(id); return 0; } id_close(id); return ident; /* At last! */ } char *ident_id __P2(int, fd, int, timeout) { IDENT *ident; char *id=0; ident = ident_lookup(fd, timeout); if (ident && ident->identifier && *ident->identifier) { id = id_strdup(ident->identifier); if (id == NULL) return NULL; } ident_free(ident); return id; } void ident_free __P1(IDENT *, id) { if (!id) return; if (id->identifier) free(id->identifier); if (id->opsys) free(id->opsys); if (id->charset) free(id->charset); free(id); } SHAR_EOF chmod 644 'ident.c' fi if test -f 'ident.3' then echo shar: "will not over-write existing file 'ident.3'" else cat << \SHAR_EOF > 'ident.3' .\" Pdr Emanuelsson 1993-03-28 .ds : \h'\w'u'u/5'\z"\h'-\w'e'u/5' .TH IDENT 3 "4 April 1993" "Lysator ACS" .SH NAME ident_lookup, ident_id, ident_free, id_open, id_close, id_query, id_parse, id_fileno \- query remote IDENT server .SH SYNOPSIS .nf .B #include .LP .I High-level calls .LP .B IDENT *ident_lookup(int fd, int timeout) .LP .B char *ident_id(int fd, int timeout) .LP .B void ident_free(IDENT *id) .LP .I Low-level calls .LP .B id_t *id_open(laddr, faddr, timeout) .B struct in_addr *laddr, *faddr; .B struct timeval *timeout; .LP .B int id_close(id) .B id_t *id; .LP .B id_query(id, lport, fport, timeout) .B id_t *id; .B int lport, fport; .B struct timeval *timeout; .LP .B int id_parse(id, timeout, lport, fport, identifier, .B opsys, charset) .B id_t *id; .B struct timeval *timeout; .B int *lport, *fport; .B char **identifier, **opsys, **charset; .LP .B int id_fileno(id) .B id_t *id; .fi .SH DESCRIPTION .LP .B ident_lookup tries to connect to a remote .B IDENT server to establish the identity of the peer connected on .I fd, which should be a socket file descriptor. .I timeout is the longest permissible time to block waiting for an answer, and is given in seconds. A value of 0 (zero) means wait indefinitely (which in the most extreme case will normally be until the underlying network times out). .B ident_lookup returns a pointer to an .I IDENT struct, which has the following contents: .RS .LP .nf .ft B typedef struct { int lport; /* Local port */ int fport; /* Far (remote) port */ char *identifier; /* Normally user name */ char *opsys; /* OS */ char *charset; /* Charset (what did you expect?) */ } IDENT; .ft R .fi .RE .LP For a full description of the different fields, refer to .I RFC-1413. .LP All data returned by .B ident_lookup (including the .SM IDENT struct) points to malloc'd data, which can be freed with a call to .B ident_free. .B ident_lookup returns 0 on error or timeout. Presently, this should normally be taken to mean that the remote site is not running an .SM IDENT server, but it might naturally be caused by other network related problems as well. .B Note that all fields of the .SM IDENT struct need not necessarily be set. .LP .B ident_id takes the same parameters as .B ident_lookup but only returns a pointer to a malloc'd area containing the .I identifier string, which is probably the most wanted data from the .SM IDENT query. .LP .B ident_free frees all data areas associated with the .SM IDENT struct pointed to by .I id, including the struct itself. .LP .ce .I Low-level calls .LP The low-level calls can be used when greater flexibility is needed. For example, if non-blocking I/O is needed, or multiple queries to the same host are to be made. .LP .B id_open opens a connection to the remote .SM IDENT server referred to by .I faddr. The timeout is specified by .I timeout. A null-pointer means wait indefinitely, while a pointer to a zero-valued .I timeval struct sets non-blocking I/O, in the same way as for .B select(2). .B id_open returns a pointer to an .B id_t datum, which is an opaque structure to be used as future reference to the opened connection. When using non-blocking I/O it might however be useful to access the underlying socket file descriptior, which can be gotten at through the .B id_fileno macro described below. .LP .B id_close closes the connection opened with .B id_open and frees all data associated with .I id. .LP .B id_query sends off a query to a remote .SM IDENT server. .I lport and .I fport are sent to the server to identify the connection for which identification is needed. .I timeout is given as for .B id_open. If successful, .B id_query returns the number of bytes sent to the remote server. If not, -1 is returned and .B errno is set. .LP .B id_parse parses the reply to a query sent off by .B id_query and returns information to the locations pointed to by .I lport, fport, identifier, opsys and .I charset. For string data .I (identifier, opsys and .I charset) pointers to malloc'd space are returned. .LP .B id_parse returns: .RS .TP 1 If completely successful. .TP -3 Illegal reply type from remote server. .I identifier is set to the illegal reply. .TP -2 Cannot parse the reply from the server. .I identifier is normally set to the illegal reply. .TP -1 On general errors or timeout. .TP 0 When non-blocking mode is set and .B id_parse has not finished parsing the reply from the remote server. .TP 2 Indicates the query/reply were successful, but the remote server experienced some error. .I identifier is set to the error message from the remote server. .RE .LP For all errors, .I errno is set as appropriate. .LP .B id_fileno is a macro that takes an .B id_t handle and returns the actual socket file descriptor used for the connection to the remote server. .SH ERRORS .TP 15 ETIMEDOUT The call timed out and non-blocking I/O was not set. .SH EXAMPLES .LP Here's an example how to handle the reply from id_reply() in the case that non-blocking I/O is set. Note that id_reply() will return 0 as long as it's not finished parsing a reply. .LP .RS .nf .nj int rcode; ... idp = id_open(...) ... while ((rcode = id_parse(idp, timeout, &lport, &fport, &id, &op, &cs)) == 0) ; if (rcode < 0) { if (errno == ETIMEDOUT) foo(); /* Lookup timed out */ else bar(); /* Fatal error */ } else if (rcode == 1) { /* Valid USERID protocol reply */ } else if (rcode == 2) { /* Protocol ERROR reply */ } .fi .RE .SH SEE ALSO RFC-1413, socket(2), select(2) .SH AUTHORS Peter Eriksson .I .br P\*:ar Emanuelsson .I .SH BUGS For .B ident_lookup and .B ident_id the blocking time in extreme cases might be as much as three times the value given in the .I timeout parameter. SHAR_EOF chmod 644 'ident.3' fi if test -f 'lookup-tester.c' then echo shar: "will not over-write existing file 'lookup-tester.c'" else cat << \SHAR_EOF > 'lookup-tester.c' /* ** lookup-tester.c Tests the high-level ident calls. ** ** Author: Pdr Emanuelsson , 28 March 1993 */ #ifdef NeXT3 # include #endif #include #ifdef HAVE_ANSIHEADERS # include # include #endif #include /* Need this to make fileno() visible when compiling with strict ANSI */ #ifndef _POSIX_C_SOURCE # define _POSIX_C_SOURCE #endif #include #define IN_LIBIDENT_SRC #include "ident.h" void main __P2(int, argc, char **, argv) { IDENT *ident; char *user; chdir("/tmp"); puts("Welcome to the other IDENT server tester, version 1.0\r\n\r"); puts("Testing ident_lookup...\r\n\r"); fflush(stdout); ident = ident_lookup(fileno(stdin), 30); if (!ident) perror("ident"); else { printf("IDENT response is:\r\n"); printf(" Lport........ %d\r\n", ident->lport); printf(" Fport........ %d\r\n", ident->fport); printf(" Opsys........ %s\r\n", ident->opsys); printf(" Charset...... %s\r\n", ident->charset ? ident->charset : ""); printf(" Identifier... %s\r\n", ident->identifier); } ident_free(ident); puts("\r\nTesting ident_id...\r\n\r"); fflush(stdout); user = ident_id(fileno(stdin), 30); if (user) printf("IDENT response is identifier = %s\r\n", user); else puts("IDENT lookup failed!\r"); fflush(stdout); sleep(1); exit(0); } SHAR_EOF chmod 644 'lookup-tester.c' fi if test -f 'version.c' then echo shar: "will not over-write existing file 'version.c'" else cat << \SHAR_EOF > 'version.c' char id_version[] = "0.20"; SHAR_EOF chmod 644 'version.c' fi if test -f 'INSTALL' then echo shar: "will not over-write existing file 'INSTALL'" else cat << \SHAR_EOF > 'INSTALL' To build the libident library for a supported target, just type: make where target can be one of: sunos5, sunos4, svr4, bsd, linux, nextstep3.0 or nextstep3.1 For other systems you'll need to hack the Makefile (please do send me any patches you make so I can include them into the next version!) - Peter Eriksson , 18 Oct 1994 SHAR_EOF chmod 644 'INSTALL' fi if test -f 'support.c' then echo shar: "will not over-write existing file 'support.c'" else cat << \SHAR_EOF > 'support.c' /* ** support.c ** ** Author: Pr Emanuelsson ** Hacked by: Peter Eriksson */ #include #include #ifdef HAVE_ANSIHEADERS # include # include #else # define strchr(str, c) index(str, c) #endif #define IN_LIBIDENT_SRC #include "ident.h" char *id_strdup __P1(char *, str) { char *cp; cp = (char *) malloc(strlen(str)+1); if (cp == NULL) { #ifdef DEBUG perror("libident: malloc"); #endif return NULL; } strcpy(cp, str); return cp; } char *id_strtok __P3(char *, cp, char *, cs, char *, dc) { static char *bp = 0; if (cp) bp = cp; /* ** No delimitor cs - return whole buffer and point at end */ if (!cs) { while (*bp) bp++; return cs; } /* ** Skip leading spaces */ while (isspace(*bp)) bp++; /* ** No token found? */ if (!*bp) return 0; cp = bp; while (*bp && !strchr(cs, *bp)) bp++; /* ** Remove trailing spaces */ *dc = *bp; for (dc = bp-1; dc > cp && isspace(*dc); dc--) ; *++dc = '\0'; bp++; return cp; } SHAR_EOF chmod 644 'support.c' fi if test ! -d 'profiled' then mkdir 'profiled' fi cd 'profiled' chmod 755 . cd .. chmod 755 . cd .. exit 0 # End of shell archive