Newsgroups: comp.sources.unix From: bcr@physics.purdue.edu (Bill C. Riemers) Subject: v28i172: term-2.2.5 - SLIP-like functionality between two *IX hosts (REPOST), Part09/09 References: <1.784237938.15304@gw.home.vix.com> Sender: unix-sources-moderator@gw.home.vix.com Approved: vixie@gw.home.vix.com Submitted-By: bcr@physics.purdue.edu (Bill C. Riemers) Posting-Number: Volume 28, Issue 172 Archive-Name: term-2.2.5/part09 #!/bin/sh # This is `part09' (part 9 of a multipart archive). # Do not concatenate these parts, unpack them in order with `/bin/sh'. # File `term-2.2.5/utils.c' is being continued... # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if test ! -r _sharseq.tmp; then echo 'Please unpack part 1 first!' exit 1 fi shar_sequence=`cat _sharseq.tmp` if test "$shar_sequence" != 9; then echo "Please unpack part $shar_sequence next!" exit 1 fi if test ! -f _sharnew.tmp; then echo 'x - still skipping term-2.2.5/utils.c' else echo 'x - continuing file term-2.2.5/utils.c' sed 's/^X//' << 'SHAR_EOF' >> 'term-2.2.5/utils.c' && X MAX_BUFF : b->alloced+BUFF_INC_SIZE)) == NULL) { X perror("%Term: realloc"); X return -1; X }else { X b->alloced += BUFF_INC_SIZE; X if (b->alloced > MAX_BUFF || b->alloced < BUFF_INC_SIZE) X b->alloced = MAX_BUFF; X } X if (!b->size) b->start=b->end=0; X X /* It took me ages to realize this is what is being done here! */ X X /* OK, we use buffers as a continuous loop. So when we reach the eob */ X /* (end of buffer) we just continue on at the bob (beginning of buffer). */ X /* So if we want to increase the size of the buffer while it is in use */ X /* we must take data at the eob and move it to the new eob so we have */ X /* more space where we need it in the mob (middle of buffer). */ X X /* This means "start" is where we can start adding more data to the */ X /* buffer, and "end" is where we last ended removing the data. */ X X if ( do_move && (b->end > b->start)) { /* curses. need to move data. */ X int i; char *new_eob, *old_eob; X new_eob = (caddr_t)b->data + b->alloced - 1; X old_eob = (caddr_t)b->data + b->alloced - BUFF_INC_SIZE - 1; X for (i = b->alloced - BUFF_INC_SIZE - b->end; i > 0; --i) X *new_eob-- = *old_eob--; X b->end += BUFF_INC_SIZE; X } X return 0; X} X X X X/*-----------------------------------------------------------------------*/ X X#ifndef O_NONBLOCK X#define O_NONBLOCK FNDELAY X#endif X Xvoid set_nonblock(int fd) { X int val = 1; /* Checker V0.5 needs assignment even if !USE_IOCTL */ X#ifdef USE_IOCTL X ioctl(fd, FIONBIO, &val); X#else X val = fcntl(fd, F_GETFL); X if (!(val & O_NONBLOCK)) X fcntl (fd, F_SETFL, val | O_NONBLOCK); X#endif X} X Xint set_block(int fd) { X int val = 0; /* Checker V0.5 needs assignment even if !USE_IOCTL */ X#ifdef USE_IOCTL X ioctl(fd, FIONBIO, &val); X return 1; X#else X val = fcntl(fd, F_GETFL); X if (val & O_NONBLOCK) X fcntl (fd, F_SETFL, val & ~O_NONBLOCK); X return !(val & O_NONBLOCK); X#endif X} X X/* Read from a file-descriptor into a ring buffer. Read at most size bytes */ Xint read_into_buff(int fd, struct Buffer *b, int z) { X int ret, l = 0, size; X X if (! b->alloced) inc_buffer(b,0); X X if ((size = z) > b->alloced - 1 - b->size) inc_buffer(b,1); X X if (!size) X size = b->alloced - 1 - b->size; X X do { X ret = do_read_into_buff(fd, b, size); X if (ret < 1) break; X l += ret; X size -= ret; X if (!z && !termerrno && !size && b->alloced < PIPE_BUFFER) { X if (inc_buffer(b,1) < 0) X termerrno = 1; X else X size = b->alloced - 1 - b->size; X } X } while (!termerrno && size); X if (!b->size) b->start=b->end=0; X if (!l) return ret; X return l; X} X X#ifdef hcx X/* Under HCX/UX 5.1 (at least), writes of 256 bytes or more can return */ X/* a -1 with errno == EAGAIN, but actually write the data successfully. */ X#undef _POSIX_PIPE_BUF X#define _POSIX_PIPE_BUF 128 X#endif X X/*------------------------------------------------------------------------*/ X/* Write from ring buffer to file descriptor. Write at most size bytes */ X Xint internal_write_from_buff(int fd, struct Buffer *b, int size, int async) { X int r = 0, t, i; X X SANITY(b->size <= b->alloced); X if (!size) size = b->size; X if (size > b->size) size = b->size; X X while (size > 0) { /* We use a loop in case there is a maximum block size */ X t = b->alloced - b->end; X if (t > size) t = size; X if (t > _POSIX_PIPE_BUF) t = _POSIX_PIPE_BUF; X X i = write(fd, b->data + b->end, t); X X if (i <= 0) { X if (!i) termerrno = 1; X#ifdef SVR3 X else if (i == -1 && errno == EINTR) continue; X#endif X else if (errno != ERR_BLOCK) X termerrno = errno+1; X return r; X } X DEBUG_LL(stderr, "%s: d_w_f_b: write from %d (%d) did %d\n", X term_server, fd, t, i); X X r += i; X X b->end += i; X b->size -= i; X size -= i; X SANITY(size <= b->size); X X SANITY(b->end <= b->alloced); X if (b->end == b->alloced) b->end = 0; X if (i != t && async) X break; X }; X if (!b->size) b->start=b->end=0; X return r; X} X Xint write_from_buff(int fd, struct Buffer *b, int size) { X return internal_write_from_buff(fd, b, size, 0); X} X Xint write_from_buff_async(int fd, struct Buffer *b, int size) { X return internal_write_from_buff(fd, b, size, 1); X} X Xint add_to_buffer(struct Buffer *B, un_char c) { X X if (! B->alloced) B->size=0; X if (B->size >= B->alloced - 2) { X X DEBUG_LL (stderr, "%s:add_to_buffer:growing buffer from %d, %d\n", X term_server, B->size, B->alloced); X X if( inc_buffer(B,(B->alloced > 0)) < 0) { X termerrno = 1; X return -1; X } X } X B->data[B->start++] = (c); X if (B->start == B->alloced) B->start = 0; X B->size++; X return 0; X} X Xint get_from_buffer(struct Buffer *b) { X un_char c; X if (b->size < 1) X return -1; X c = b->data[b->end++]; X --b->size; X if (b->end >= b->alloced) X b->end = 0; X if (!b->size) b->start=b->end=0; X return (int) c&255; X} X/*-----------------------------------------------------------------------*/ X X /* KLUDGE. suns always need stderr, so ignore the config.h if */ X /* it says otherwise. This is mostly just a sanity check */ X#if !defined(NO_STRERROR) && !defined(_LIBC) Xchar *strerror(int errno) { X extern char *sys_errlist[]; X X return sys_errlist[errno]; X} X#endif X X /* This is to allow easy checking of effective access */ Xint eaccess(char *pathname, int mode){ X struct stat file_status; X int m; X X if(stat(pathname,&file_status) == -1) return -1; X if(! mode) return 0; X X if(file_status.st_uid == geteuid()) X m = mode << 6; X else if ( file_status.st_gid == getegid()) X m = mode << 3; X else X m = mode; X X return - ((file_status.st_mode & m) != m) ; X} X X /* This tests whether we are in shared mode */ Xvoid set_share_mode(int priv, int share_new){ X char *e; X static int share_old = -2; X X share = share_new; X if (share_old == -2) { X e = getenv("TERMMODE"); X if (e) X share_old = atoi(e); X if(share_old < 0 || share_old > 2) share_old = -1; X } X X if (share_old != share) { X#ifdef _POSIX_SAVED_IDS X if (savedeid >= 0) { X if (share > 1) X setgid(savedeid); X else if (share > 0) X setgid(savedeid); X savedeid = -1; X } X#endif X if (share < 0) share = share_old; X } X X if (share < 0) { X share = (getgid() != getegid()); X if (! share) X share = (getuid() != geteuid() && getuid()) ? 2 : -1; X } X X if (! share) { X if (getgid() != getegid()) X setgid(getgid()); X else if (geteuid() != 0 && geteuid() != getuid()) X setuid(getuid()); X } X#ifdef _POSIX_SAVED_IDS X else if (share > 0 && savedeid < 0){ X if ( share == 2 ) { X savedeid = geteuid(); X setuid(getuid()); X }else { X savedeid = getegid(); X setgid(getgid()); X } X } X#endif X X if (share != share_old) X share_old = share; X X if (priv) { X#ifdef _POSIX_SAVED_IDS X savedeid = -1; X#endif X if (geteuid() && geteuid() != getuid()) setuid(getuid()); X if (getegid() && getegid() != getgid()) setgid(getgid()); X } X} X Xchar *str_version(long unsigned int version){ X static char v[25]; X if(version%100 < 50 ) /* These are bug fix releases */ X sprintf(v, "%lu.%lu.%lu",(version/10000), X (version/100)%100,version%100); X else if(version%100 < 77 ) /* These are alpha releases */ X sprintf(v, "%lu.%lu%c (alpha)",(version/10000), X (version/100)%100,'a'+(char)((version-51)%100)); X else if(version%100 < 90 ) /* These are alpha releases */ X sprintf(v, "%lu.%lu%c%c (alpha)\r\n",(version/10000), X (version/100)%100,'z','a'+(char)((version-77)%100)); X else X sprintf(v, "alpha pre-release of %lu.%02lu pl %02lu",(version/10000), X 1+(version/100)%100,version%10); X return v; X} X X /* This is an unreliable protocol. So in the case of errors */ X /* we must just try to continue the best we can. */ X Xint recvfrom_into_buff(struct Client *cl) { X struct sockaddr_in from_addr; X int r = 0, i, fd, type; X struct Buffer *b; X static un_char *from = NULL; X static size_t alloced = 0; X unsigned int avail = 0, len, hdr = 0, t; X unsigned long lhost, *host; X unsigned int lport, *port; X X host = &cl->udp_host; X port = (unsigned int *)&cl->udp_port; X X fd = cl->fd; X b = &cl->in_buff; X type = cl->udp_type; X X termerrno = 0; X X DEBUG_UDP(stderr,"%s# recvfrom_i_b called.\n",term_server); X X#ifndef FIONREAD X /* X * System V release 3 doesn't have an FIONREAD even on sockets, but X * in looking at the code it looks like a select here just to tell X * if there is any data available is sufficient. Size is always set X * to PIPE_BUFFER or greater so I suspect if I just read PIPE_BUFFER I'll X * be OK. It might require bumping PIPE_BUFFER up to the maximum message X * size. X */ X { X struct pollfd fds[2]; X int status; X X fds[0].fd = fd; X fds[0].events = POLLIN | POLLPRI | POLLERR | POLLHUP; X fds[0].revents = 0; X X errno = 0; X status = -1; X while (status == -1) { X status = poll(fds, 1L, 2); X if (errno != EAGAIN) X break; X } X X if (status == -1) { X perror("ERROR in poll request"); X return 0; X } X X if (fds[0].revents & POLLIN | POLLPRI) X avail = PIPE_BUFFER; X else X return 0; X } X#else X if( ioctl( fd, FIONREAD, &avail) < 0) return 0; X#endif X if (avail < PIPE_BUFFER) avail = PIPE_BUFFER; X X if( type & UDP_T_RECADDHDR) hdr = HEADER_SIZE; else hdr = 0; X X if ( ! from) { X from = (un_char *)malloc(sizeof(un_char)*BUFF_INC_SIZE); X alloced = BUFF_INC_SIZE; X } X SANITY(alloced); X X while ( from && (avail+hdr) > alloced && alloced < MAX_BUFF) { X from = (un_char *)realloc(from,sizeof(un_char)* X ((alloced+BUFF_INC_SIZE > MAX_BUFF) ? X MAX_BUFF : alloced+BUFF_INC_SIZE)); X alloced += BUFF_INC_SIZE; X break; X } X if (alloced > MAX_BUFF) alloced = MAX_BUFF; X avail = alloced; X X if (! from) { /* OK, this seems like a reasonable exception... */ X alloced = 0; X termerrno = 1; X return -1; X } X X len = sizeof(from_addr); X if ((i = recvfrom(fd, from+hdr+2, avail, 0, X (struct sockaddr *)&from_addr, (int *)&len)) < 0) { X DEBUG_UDP(stderr,"recvfrom %d : %s\n", avail,strerror(errno)); X /* We failed, thats tuff, we should still */ X /* Leave the socket open to try again... */ X free(from); X from = NULL; X alloced = 0; X return 0; X } X SANITY(avail <= alloced); X X DEBUG_UDP(stderr,"%s# recvfrom()'d: host %lx, port %d.\n", term_server, X (long)ntohl(from_addr.sin_addr.s_addr), X ntohs(from_addr.sin_port)); X X DEBUG_UDP(stderr,"# state 1: avail %d, avail+hdr %d, i %d, b->size %d.\n", X avail, avail+hdr, i, b->size); X X avail = i + hdr + 2; X lhost = ntohl(from_addr.sin_addr.s_addr); X lport = ntohs(from_addr.sin_port); X if (type & UDP_T_RECADDHDR) { X from[2] = (lhost>>24)&255; X from[3] = (lhost>>16)&255; X from[4] = (lhost>>8)&255; X from[5] = lhost&255; X from[6] = (lport>>8)&255; X from[7] = lport&255; X } X X if ( ! *host || ! *port ) { X *host = lhost; X *port = lport; X } X X while( avail > (b->alloced - b->size) && b->alloced < MAX_BUFF) { /* +HEADER_SIZE just to make sure... */ X if( inc_buffer(b,1) < 0) { X termerrno = 1; /* Our buffer is gone, so we have no choice but to */ X /* report this error. */ X return -1; X } X } X X /* If necessary, truncate the message, and store the size */ X X if ( avail > (b->alloced - b->size) ) avail = b->alloced - b->size; X from[0] = (avail>>8)&255; X from[1] = avail & 255; X X /* We must be careful here, since there is no guarantee that the */ X /* available memory in the buffer is continuous!! */ X X /* The first chunk. */ X X t = b->alloced - b->start; X if( t > avail) t = avail; /* do it ALL at once */ X X DEBUG_UDP(stderr,"%s# state 2: t %d, avail+hdr+2 %d.\n", term_server, t, avail); X X memcpy( b->data + b->start, from, t); /* bugger checking the return code... */ X X b->start += t; X if( b->start == b->alloced) X b->start = 0; X b->size += t; X X X DEBUG_UDP(stderr,"%s# state 3: b->start %d, b->size %d.\n", term_server, X b->start, b->size); X X if (t == avail) { /* all done, return */ X DEBUG_UDP(stderr,"%s# return 1 (%d) - all done.\n", term_server, t); X return (int) t; X } X X /* The memory wasn't continuous, so now we need to get the rest. */ X X r = avail - t; X X DEBUG_UDP(stderr,"%s# round 2: r %d.\n", term_server,r); X X SANITY(b->start == 0); X memcpy( b->data, from + t, r); /* b->start needed? */ X X b->start += r; X SANITY(b->start < b->alloced); X b->size += r; X X DEBUG_UDP(stderr,"%s# state 3: r %d, b->start %d, b->size %d.\n", term_server, X r, b->start, b->size); X DEBUG_UDP(stderr,"%s# return 2 (%d) - all done.\n", term_server, avail+hdr); X X /* Now we are really done. */ X X return (int) avail; X} X X X X/* ------------------------------------------------------------------------------ X * send to_from_buff() X * basically, transfer from Buffer *b to the array *to and returns the number of X * chars send. X * X * also, take care of the header... header is the first HEADER_SIZE bytes of the X * packet telling host/port to sendto()'it (or host/port it was recvfrom()''ed) X * ans the size of the packet, INCLUDING header. X * X */ X X X /* This is an unreliable protocol. So in the case of errors */ X /* we must just try to continue the best we can. If we are able */ X /* to try another message, we shouldn't return an error. */ X Xint sendto_from_buff(struct Client *cl) { X int type, *port; X int r=0, t, i; X struct Buffer *b; X unsigned long int *host; X unsigned long int lhost; X unsigned short int lport; X struct sockaddr_in toaddr_in; X static un_char *to = NULL; X static size_t alloced = 0; X X b = &cl->out_buff; X type = cl->udp_type; X host = &cl->udp_host; X port = &cl->udp_port; X X termerrno = 0; /* this sucker cost be around 2 hours of debugging! :) */ X X DEBUG_UDP(stderr,"%s@ sendto_from_buff called.\n",term_server); X DEBUG_UDP(stderr,"%s@b->size %u b->end %d\n",term_server, X b->size, b->end); X X /* If we don't have the header yet we can't do anything. */ X if ( ! b->alloced || b->size < 2 ) { X DEBUG_UDP(stderr,"%s@only have one udp byte.\n",term_server); X cl->udp_size=b->size; X return 0; X } X cl->udp_size = X (b->data[b->end]<<8) + X (b->data[(b->end + 1) % b->alloced]&255); X X if (cl->udp_size < HEADER_SIZE+2 || cl->udp_size > MAX_BUFF) { X DEBUG_UDP(stderr,"%s@ term invalid udp packet size.\n",term_server); X cl->udp_size=b->size=b->start=b->end=0; X termerrno = 1; /* OK, once we have an internal error like this */ X return -1; /* we are doomed. */ X } X X if (b->size < cl->udp_size) { X DEBUG_UDP(stderr,"%s@udp message is not complete yet. %d/%d\n", X term_server, b->size, cl->udp_size); X return 0; /* I'll be back. */ X } X X if (b->size - 2 < HEADER_SIZE) { X DEBUG_UDP(stderr,"%s@term udp packet is too small.\n",term_server); X cl->udp_size=b->size=b->start=b->end=0; X termerrno = 1; /* OK, once we have an internal error like this */ X return -1; /* we are doomed. */ X } X b->size -= 2; X b->end = (b->end + 2) % b->alloced; X cl->udp_size -= 2; X X if (! to) { X to = (un_char *)malloc(sizeof(un_char)*BUFF_INC_SIZE); X alloced = BUFF_INC_SIZE; X } X SANITY(alloced); X X while (to && cl->udp_size > alloced && alloced < MAX_BUFF) { X to = (un_char *)realloc(to,sizeof(un_char)* X ((alloced+BUFF_INC_SIZE > MAX_BUFF) ? X MAX_BUFF : alloced+BUFF_INC_SIZE)); X alloced += BUFF_INC_SIZE; X } X X if (! to) { /* Not much we can do if we are out of memory! */ X DEBUG_UDP(stderr,"%s@ allocation failure.\n",term_server); X alloced = 0; X termerrno = 1; X return -1; X } X X if (alloced > MAX_BUFF) alloced = MAX_BUFF; X SANITY(alloced >= BUFF_INC_SIZE); X X if ( cl->udp_size > alloced ) cl->udp_size = alloced; /* Anyone sending too large of a */ X /* udp message deserves what they get. */ X t = cl->udp_size; X if (t > b->alloced - b->end) t = b->alloced - b->end; X X DEBUG_UDP(stderr,"@ 1st chunk: t %d, b->end %d\n",t,b->end); X SANITY(to && b->data); X memcpy(to, b->data + b->end, t); X X b->size -= t; X b->end = (b->end + t) % b->alloced; X X if ((r = cl->udp_size - t) > 0) { X SANITY(r <= b->size); X SANITY(b->end == 0); X DEBUG_UDP(stderr,"@ 2nd chunk: r %d , b->end %d\n",r,b->end); X memcpy (to + t, b->data, r); X b->size -= r; X b->end = (b->end + r) % b->alloced; X t += r; X } X X if (!b->size) b->start=b->end=0; X X lhost = (to[0]<<24)+(to[1]<<16)+(to[2]<<8)+(to[3]); X lport = (to[4]<<8)+(to[5]); X DEBUG_UDP(stderr,"%s@message from %lx, %u\n",term_server,lhost,lport); X X if ( !(type & UDP_T_SENDIGNOREHDR) && (lhost || lport)) { X /* don't ignore header, therefore put it in *host *port for sendto()'ing */ X DEBUG_UDP(stderr,"%s@ changing: from *host, *port %lx, %u to ", X term_server, *host, *port); X *host = lhost; X *port = lport; X DEBUG_UDP(stderr,"%lx, %u\n",*host, *port); X } X X toaddr_in.sin_family = AF_INET; X toaddr_in.sin_addr.s_addr = htonl(*host); X toaddr_in.sin_port = htons(*port); X if (toaddr_in.sin_addr.s_addr == INADDR_ANY || X toaddr_in.sin_addr.s_addr == inet_addr("127.0.0.254")) X toaddr_in.sin_addr.s_addr = inet_addr("127.0.0.1"); X X if( type & UDP_T_SENDSTRIPHDR) /* strip header before sending? */ X i = sendto(cl->fd, to + HEADER_SIZE, t - HEADER_SIZE, 0, X (struct sockaddr *)&toaddr_in, sizeof(toaddr_in)); X else X i = sendto(cl->fd, to, t, 0, X (struct sockaddr *)&toaddr_in, sizeof(toaddr_in)); X X cl->udp_size = 0; X DEBUG_UDP(stderr,"%s@b->size %u b->end %d\n", X term_server, b->size, b->end); X X if (i < 0) { X DEBUG_UDP(stderr,"%s@ return 2.5 (%d) %lx, %u - sendto() failed.\n", X term_server, i, *host, *port); X *host = 0; /* This unbinds the socket... */ X *port = 0; X return t + 2; /* Another error. Tuff luck. */ X } X X DEBUG_UDP(stderr,"%s@ return 3 (%d) - did sendto(): host %lx, port %u, i %d\n", X term_server, t, *host, *port, i); X X return t + 2; X} X X X/* This is grossly overly complicated because I try to convert invalid */ X/* addresses to something recognizable */ X Xchar *sockaddr_to_sstr(struct sockaddr *addr, int trans) { X return NULL; X} X X Xvoid get_term_localaddr(unsigned long default_addr) { X char hostname[sizeof(term_localhost)]; X struct hostent *hp; X struct in_addr addr_in; X X if (term_localaddr != INADDR_ANY) return; X X memset(term_localhost,0,sizeof(term_localhost)); X#if defined(SYSV) && !defined(DYNIXPTX) X { struct utsname unam; X uname(&unam); X strcpy(hostname, unam.nodename); } X#else X gethostname (hostname, sizeof(hostname)); X#endif X strcpy(term_localhost, hostname); X if (hostname[0] >= '0' && hostname[0] <= '9') { X addr_in.s_addr = inet_addr(hostname); X }else { X hp=host_lookup(hostname,0,AF_INET,0,NULL); X if (!hp) { X extern int h_errno; X fprintf(stderr,"%s: gethostbyname: %s: %s\n",term_server, hostname, X term_strherror(h_errno)); X addr_in.s_addr = default_addr; X strcpy (term_localhost, "127.0.0.1"); X }else { X memcpy(&addr_in, hp->h_addr, hp->h_length); X } X } X term_localaddr = ntohl(addr_in.s_addr); X} X Xchar *sockaddr_to_str(struct sockaddr *addr, int trans) { X struct sockaddr_in addr_in; X static char portname[24]; X unsigned long int j; X char *a,*p; X X#define UC(y) (int) ((int) 0xff & (int) (y)) X memset(&addr_in,0,sizeof(struct sockaddr_in)); X memcpy(&addr_in,addr,sizeof(struct sockaddr_in)); X p = (char *)&addr_in.sin_port; X X if ( ! addr_in.sin_addr.s_addr || addr_in.sin_family != AF_INET ){ X struct hostent *hp; X char hostname[259]; X X#if defined(SYSV) && !defined(DYNIXPTX) X { struct utsname unam; X uname(&unam); X strcpy(hostname, unam.nodename); } X#else X gethostname (hostname, sizeof(hostname)); X#endif X if (hostname[0] >= '0' && hostname[0] <= '9') { X addr_in.sin_addr.s_addr = inet_addr(hostname); X }else { X hp=host_lookup(hostname,0,AF_INET,0,NULL); X if (!hp) { X herror ("Term: gethostbyname"); X addr_in.sin_addr.s_addr = INADDR_ANY; X }else { X memcpy(&addr_in.sin_addr, hp->h_addr, hp->h_length); X } X } X }; X j = addr_in.sin_addr.s_addr; X if ( trans && (! j || j == INADDR_ANY || j == inet_addr("127.0.0.1"))) X j = ( remote_term_version >= 20000 ) ? X inet_addr("127.0.0.254") : inet_addr("127.0.0.1"); X a = (char *)&j; X (void) sprintf(portname, "%u,%u,%u,%u,%u,%u", X UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); X return portname; X} X Xstruct sockaddr *sstr_to_sockaddr(char *addr, unsigned long defaultaddr){ X return NULL; X} X Xstruct sockaddr *str_to_sockaddr(char *addr, unsigned long defaultaddr){ X static struct sockaddr_in name_in; X int j; X char port[35], *u, *v; X X strncpy(port,addr,35); X for(j=0;j<3;j++) *strchr(port,',')='.'; X u=strchr(port,','); X *u='\0'; X v=strchr(++u,','); X *v='\0'; X X name_in.sin_addr.s_addr = inet_addr(port); X if ( name_in.sin_addr.s_addr == INADDR_ANY X || name_in.sin_addr.s_addr == inet_addr("127.0.0.1") X || name_in.sin_addr.s_addr == inet_addr("127.0.0.254") ) X name_in.sin_addr.s_addr = defaultaddr; X X name_in.sin_family = AF_INET; X name_in.sin_port = htons((atoi(u)<<8)+atoi(++v)); X return (struct sockaddr *)&name_in; X} X X Xstruct sockaddr *make_sockaddr(unsigned int port, char *host, X unsigned long defaulthost) { X static struct sockaddr_in addr_in; X struct hostent *hp; X char *hostname=NULL, *colon; X int s=259; X X memset(&addr_in,0,sizeof(addr_in)); X if (host) X s = (strlen(host)+1 < 259) ? 259 : strlen(host)+1; X X hostname = (char *)malloc(sizeof(char)*s); X *hostname = '\0'; X if (host) { X strcpy(hostname,host); X if ((colon = strchr(hostname,':'))) *colon = '\0'; X }else if (defaulthost != INADDR_ANY) { X#if defined(SYSV) && !defined(DYNIXPTX) X { struct utsname unam; X uname(&unam); X strcpy(hostname, unam.nodename); X } X#else X gethostname (hostname, sizeof(hostname)); X#endif X } X X addr_in.sin_family = AF_INET; X if (! *hostname || ! strcmp(hostname,"localhost") X || ! strcmp(hostname,"remotehost") X || ! strcmp(hostname,"127.0.0.1") X || ! strcmp(hostname,"127.0.0.254") ) { X addr_in.sin_addr.s_addr = defaulthost; X }else if (hostname[0] >= '0' && hostname[0] <= '9') { X addr_in.sin_addr.s_addr = inet_addr(hostname); X }else { X hp=host_lookup(hostname,0,AF_INET,0,NULL); X if (!hp) { X if (host) { X fprintf(stderr,"Term: gethostbyname "); X herror (hostname); X if (hostname) free(hostname); X return NULL; X } X addr_in.sin_addr.s_addr = defaulthost; X addr_in.sin_family = AF_INET; X }else { X memcpy(&addr_in.sin_addr, hp->h_addr, hp->h_length); X addr_in.sin_family = hp->h_addrtype; X } X } X X if (hostname) free(hostname); X addr_in.sin_port = htons(port); X return (struct sockaddr *)&addr_in; X} X X Xchar *get_term_path(char **ptr) { X int len; X static char path[PATH_MAX]; X static char *home_p = NULL, *share_p = NULL; X char *p = NULL; X X path[0] = '\0'; X X#define DEFAULT_PATH SHAREDIR ":/usr/local/lib/term:/usr/lib/term:/usr/etc:/etc" X X if (!home_p && !share) { X *ptr = NULL; X p = getenv( "TERMDIR" ); X if (!p) p = getenv( "HOME" ); X if (!p) p = ""; X X home_p = (char *)malloc( sizeof(char) * (strlen(p)+strlen(DEFAULT_PATH)+2) ); X sprintf(home_p,"%s:%s",p,DEFAULT_PATH); X } X X if (!share_p && share) { X *ptr = NULL; X p = getenv( "TERMSHARE" ); X if (!p) p = ""; X X share_p = (char *)malloc( sizeof(char) * (strlen(p)+strlen(DEFAULT_PATH)+2) ); X sprintf(share_p,"%s:%s",p,DEFAULT_PATH); X } X X if ( ! *ptr ) { X if (share) X p = share_p; X else X p = home_p; X }else p = strchr(*ptr, ':'); X X if (p) { X char *q; X X while (*p == ':') p++; X len = strlen(p) + 1; X strncpy(path, p,(len > sizeof(path)) ? sizeof(path) : len); X if ((q=strchr(path,':'))) *q = '\0'; X } X X *ptr = p; X if (! *path) X return NULL; X return path; X} X X#define CKSBUF 2048 X X/* Run a 16-bit CRC over the first nbytes of the given file X Beware, this eats CPU... -ot X*/ Xunsigned short file_crc(char *fname, long nbytes) X{ X char buf[CKSBUF]; X unsigned short sum = 0; X int f, i, n = 0; X X if ((f = open(fname, O_RDONLY)) <0) X return 0; X while (nbytes>0) { X if ((n = read(f, buf, nbytes _sharnew.tmp echo 'x - extracting term-2.2.5/xconn.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'term-2.2.5/xconn.c' && X#define I_ERRNO X#define I_SYS X#define I_IOCTL X#define I_STRING X#define I_SIGNAL X#define I_GETOPT X#define I_CTYPE X X#include "includes.h" X Xchar *local_x = "/tmp/.X11-unix/X0"; X X#ifdef SCO X#define DEFAULT_DISPLAY_NUM 7 X#else X#define DEFAULT_DISPLAY_NUM 9 X#endif X Xint display_num = DEFAULT_DISPLAY_NUM; X X#ifdef ONE_CLIENT X# define main txconn X#else Xint term_debug = 0; X#endif X#ifdef UNIX_AND_TCP_SOCKETS X int j; X#endif X Xint xc_connect_server(int dummy, struct sockaddr *addr) { X int s; X signal(SIGPIPE, SIG_IGN); X if ((s = connect_server(term_server)) < 0) X return -1; X X if (send_command(s, C_X_SERVER, 0, "%s", local_x) < 0) X return -1; X X send_command(s, C_DUMB, 1, 0); X X return s; X} X X Xint main(int argc, char *argv[]) { X int s; X char *home; X char *display=NULL, *rdisplay=""; X int svs[1]; X#ifdef UNIX_SOCKET X char unix_sock[110]; X#endif X#ifdef UNIX_AND_TCP_SOCKETS X int j; X#endif X X (void) client_options(argc, argv,"",NULL); X setbuf(stderr, 0); X X if (term_optind < argc) X display = argv[term_optind]; X else X display = getenv("DISPLAY"); X X#ifdef UNIX_SOCKET X if (display && *display) { X rdisplay = (char *)malloc(sizeof(char)*strlen(display)); X strcpy(rdisplay, display); X *(strchr(rdisplay,':')) = '\0'; X }else if (!display || display[0] != ':' || !display[1]) X display = ":9"; X X sprintf(unix_sock,"/tmp/.X11-unix"); X mkdir(unix_sock, 0700); X strcat(unix_sock, "/X"); X strcat(unix_sock, display+1); X X#ifdef UNIX_AND_TCP_SOCKETS X if ((j=fork()) < 0) X exit(1); X else if (j) { X#endif X if ((s = bind_unix(unix_sock)) < 0) { X fprintf(stderr, "Unable to bind unix socket\n"); X exit(1); X } X#ifdef UNIX_AND_TCP_SOCKETS X } else { X if (( s = bind_tcp(6000 + (unsigned int) display_num)) == -2 || s == -1) { X fprintf(stderr, "Unable to bind tcp socket\n"); X exit(1); X } X } X#endif X X#else /* if a TCP socket.. */ X#ifdef X_STREAMS_PIPE X /* Try and work out what display we */ X /* should get by default. */ X if (!display || !display[0]) { /* is there a DISPLAY set?? */ X display_num = DEFAULT_DISPLAY_NUM; /* No. Just pick 9 by default */ X } else { X home = strchr(display,':'); /* Yes. Find out what display number.*/ X if (home) if (isdigit(home[1])) { /* If we can work it out.. */ X display_num = atoi(home+1); /* then grab the number. */ X rdisplay = (char *)malloc(sizeof(char)*strlen(display)+9); X strcpy(rdisplay,display); X home = strchr(rdisplay,':'); X *home = 0; X } X if (display_num < 0) /* if the number is invalid, */ X display_num = DEFAULT_DISPLAY_NUM; /* just default. */ X } X X if ((s = open_stream_pipe(display_num)) < 0) { X fprintf(stderr, "cannot open streams pipe\n"); X exit(1); X } X X#else X /* Try and work out what display we */ X /* should get by default. */ X if (!display || !display[0]) { /* is there a DISPLAY set?? */ X display_num = DEFAULT_DISPLAY_NUM; /* No. Just pick 9 by default */ X } else { X home = strchr(display,':'); /* Yes. Find out what display number. */ X if (home) if (isdigit(home[1])) { /* If we could work it out.. */ X display_num = atoi(home+1); /* then grab the number. */ X rdisplay = (char *)malloc(sizeof(char)*strlen(display)+9); X strcpy(rdisplay,display); X home = strchr(rdisplay,':'); X *home = 0; X } X if (display_num < 0) /* if the number is invalid, */ X display_num = DEFAULT_DISPLAY_NUM; /* just default. */ X } X X while (( s = bind_tcp_listen(6000 + (unsigned int) display_num,5)) == -2) { X if (display_num > 100) { X printf("Unable to bind socket\n"); X exit(1); X } X ++display_num; X } X X#endif X#endif X/* Set the display for any new term clients ... */ X#ifdef UNIX_AND_TCP_SOCKETS X if (j) X#endif X { X int s2 = socket_connect_server(-1,term_server); X if (s2 < 0 ) { X fprintf(stderr, "Term: %s\n", command_result); X exit(1); X } X send_command(s2, C_PUTENV, 1, "DISPLAY=%s:%d", rdisplay,display_num); X close(s2); X fprintf(stderr,"Xconn bound to DISPLAY=%s:%d\n",rdisplay,display_num); X printf("%s:%d\n",rdisplay,display_num); X } X X svs[0] = s; X do_connect(1, svs, xc_connect_server); /* Never exits. */ X exit(0); X} SHAR_EOF $shar_touch -am 1028144694 'term-2.2.5/xconn.c' && chmod 0644 'term-2.2.5/xconn.c' || echo 'restore of term-2.2.5/xconn.c failed' shar_count="`wc -c < 'term-2.2.5/xconn.c'`" test 4197 -eq "$shar_count" || echo "term-2.2.5/xconn.c: original size 4197, current size $shar_count" rm -f _sharnew.tmp fi rm -f _sharseq.tmp echo 'You have unpacked the last part' exit 0