예제 #1
0
int
XSetClassHint(
	Display *dpy,
	Window w,
	XClassHint *classhint)
{
	char *class_string;
	char *s;
	int len_nm, len_cl;

	len_nm = safestrlen(classhint->res_name);
	len_cl = safestrlen(classhint->res_class);
	if ((class_string = s = Xmalloc((unsigned) (len_nm + len_cl + 2)))) {
	    if (len_nm) {
		strcpy(s, classhint->res_name);
		s += len_nm + 1;
	    }
	    else
		*s++ = '\0';
	    if (len_cl)
		strcpy(s, classhint->res_class);
	    else
		*s = '\0';
	    XChangeProperty(dpy, w, XA_WM_CLASS, XA_STRING, 8,
			    PropModeReplace, (unsigned char *) class_string,
			    len_nm+len_cl+2);
	    Xfree(class_string);
	}
	return 1;
}
예제 #2
0
int
XSetCommand (
	Display *dpy,
	Window w,
	char **argv,
	int argc)
{
	register int i;
	register int nbytes;
	register char *buf, *bp;
	for (i = 0, nbytes = 0; i < argc; i++) {
		nbytes += safestrlen(argv[i]) + 1;
	}
	if ((bp = buf = Xmalloc((unsigned) nbytes))) {
	    /* copy arguments into single buffer */
	    for (i = 0; i < argc; i++) {
		if (argv[i]) {
		    (void) strcpy(bp, argv[i]);
		    bp += strlen(argv[i]) + 1;
		}
		else
		    *bp++ = '\0';
	    }
	    XChangeProperty (dpy, w, XA_WM_COMMAND, XA_STRING, 8,
			     PropModeReplace, (unsigned char *)buf, nbytes);
	    Xfree(buf);
	}
	return 1;
}
예제 #3
0
int
XSetStandardProperties (
    	Display *dpy,
    	Window w,		/* window to decorate */
    	_Xconst char *name,	/* name of application */
    	_Xconst char *icon_string,/* name string for icon */
	Pixmap icon_pixmap,	/* pixmap to use as icon, or None */
    	char **argv,		/* command to be used to restart application */
    	int argc,		/* count of arguments */
    	XSizeHints *hints)	/* size hints for window in its normal state */
{
	XWMHints phints;
	phints.flags = 0;

	if (name != NULL) XStoreName (dpy, w, name);

	if (icon_string != NULL) {
	    XChangeProperty (dpy, w, XA_WM_ICON_NAME, XA_STRING, 8,
		PropModeReplace, (unsigned char *)icon_string, safestrlen(icon_string));
		}

	if (icon_pixmap != None) {
		phints.icon_pixmap = icon_pixmap;
		phints.flags |= IconPixmapHint;
		}
	if (argv != NULL) XSetCommand(dpy, w, argv, argc);

	if (hints != NULL) XSetNormalHints(dpy, w, hints);

	if (phints.flags != 0) XSetWMHints(dpy, w, &phints);

	return 1;
}
예제 #4
0
int
XSetFontPath (
    register Display *dpy,
    char **directories,
    int ndirs)
{
	register int n = 0;
	register int i;
	register int nbytes;
	char *p;
	register xSetFontPathReq *req;
	int retCode;

        LockDisplay(dpy);
	GetReq (SetFontPath, req);
	req->nFonts = ndirs;
	for (i = 0; i < ndirs; i++) {
		n += safestrlen (directories[i]) + 1;
	}
	nbytes = (n + 3) & ~3;
	req->length += nbytes >> 2;
	if ((p = Xmalloc (nbytes))) {
		/*
	 	 * pack into counted strings.
	 	 */
		char	*tmp = p;

		for (i = 0; i < ndirs; i++) {
			register int length = safestrlen (directories[i]);
			*p = length;
			memcpy (p + 1, directories[i], length);
			p += length + 1;
		}
		Data (dpy, tmp, nbytes);
		Xfree ((char *) tmp);
		retCode = 1;
	}
	else
		retCode = 0;

        UnlockDisplay(dpy);
	SyncHandle();
	return (retCode);
}
예제 #5
0
파일: errormsg.c 프로젝트: Distrotech/lprng
const char *Decode_status (plp_status_t *status)
{
    static char msg[LINEBUFFER];

	int n;
    *msg = 0;		/* just in case! */
    if (WIFEXITED (*status)) {
		n = WEXITSTATUS(*status);
		if( n > 0 && n < 32 ) n += JFAIL-1;
		(void) plp_snprintf(msg, sizeof(msg),
		"exit status %d (%s)", WEXITSTATUS(*status),
				 Server_status(n) );
    } else if (WIFSTOPPED (*status)) {
		(void) strcpy(msg, "stopped");
    } else {
		(void) plp_snprintf(msg, sizeof(msg), "died%s",
			WCOREDUMP (*status) ? " and dumped core" : "");
		if (WTERMSIG (*status)) {
			(void) plp_snprintf(msg + safestrlen (msg), sizeof(msg)-safestrlen(msg),
				 ", %s", Sigstr ((int) WTERMSIG (*status)));
		}
    }
    return (msg);
}
예제 #6
0
파일: errormsg.c 프로젝트: Distrotech/lprng
 static void use_syslog(int kind, char *msg)
{
    /* testing mode indicates that this is not being used
     * in the "real world", so don't get noisy. */

	/* we get rid of first set of problems - stupid characters */
	char buffer[SMALLBUFFER];
	plp_snprintf(buffer,sizeof(buffer)-1, "%s",msg);
	msg = buffer;

#ifndef HAVE_SYSLOG_H
	/* Note: some people would open "/dev/console", as default
		Bad programmer, BAD!  You should parameterize this
		and set it up as a default value.  This greatly aids
		in testing for portability.
		Patrick Powell Tue Apr 11 08:07:47 PDT 1995
	 */
	int Syslog_fd;
	if	(Syslog_fd = open( Syslog_device_DYN,
				O_WRONLY|O_APPEND|O_NOCTTY, Spool_file_perms_DYN )) > 0 ) ){
		int len;

		Max_open( Syslog_fd);
		len = safestrlen(msg);
		msg[len] = '\n';
		msg[len+1] = 0;
		Write_fd_len( Syslog_fd, msg, len+1 );
		close( Syslog_fd );
		msg[len] = 0;
    }

#else                           /* HAVE_SYSLOG_H */
# ifdef HAVE_OPENLOG
	/* use the openlog facility */
	openlog(Name, LOG_PID | LOG_NOWAIT, SYSLOG_FACILITY );
	syslog(kind, "%s", msg);
	closelog();

# else
    (void) syslog(SYSLOG_FACILITY | kind, "%s", msg);
# endif							/* HAVE_OPENLOG */
#endif                          /* HAVE_SYSLOG_H */
}
예제 #7
0
/*************************************************************************
 * Receive_secure() - receive a secure transfer
 *************************************************************************/
int Receive_secure( int *sock, char *input )
{
	char *printername;
	char error[SMALLBUFFER];	/* error message */
	char *authtype;
	char *cf, *s;
	char *jobsize = 0;
	char *user = 0;
	int tempfd = -1;
	int ack, status, from_server;
	struct line_list args, header_info, info;
	struct stat statb;
	char *tempfile = 0;
	const struct security *security = 0;

	Name = "RCVSEC";
	memset( error, 0, sizeof(error));
	ack = 0;
	status = 0;

	DEBUGF(DRECV1)("Receive_secure: input line '%s'", input );
	Init_line_list( &args );
	Init_line_list( &header_info );
	Init_line_list( &info );

	Split(&args,input+1,Whitespace,0,0,0,0,0,0);
	DEBUGFC(DRECV1)Dump_line_list("Receive_secure - input", &args);
	if( args.count != 5 && args.count != 4 ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("bad command line '%s'"), input );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}
	Check_max(&args,1);
	args.list[args.count] = 0;

	/*
     * \REQ_SECUREprintername C/F user authtype jobsize\n - receive a job
     *              0           1   2  3        4
	 */
	printername = args.list[0];
	cf = args.list[1];
	user = args.list[2];	/* user is escape encoded */
	Unescape(user);
	authtype = args.list[3];
	Unescape(authtype);
	jobsize = args.list[4];

	setproctitle( "lpd %s '%s'", Name, printername );

	Perm_check.authtype = authtype;
	from_server = 0;
	if( *cf == 'F' ){
		from_server = 1;
	}

	/* set up the authentication support information */

	if( Is_clean_name( printername ) ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("bad printer name '%s'"), input );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}

	Set_DYN(&Printer_DYN,printername);

	if( Setup_printer( printername, error+1, sizeof(error)-1, 0 ) ){
		if( jobsize ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("bad printer '%s'"), printername );
			ack = ACK_FAIL;	/* no retry, don't send again */
			status = JFAIL;
			goto error;
		}
	} else {
		int db, dbf;

		db = Debug;
		dbf = DbgFlag;
		s = Find_str_value(&Spool_control,DEBUG);
		if(!s) s = New_debug_DYN;
		Parse_debug( s, 0 );

		if( !(DRECVMASK & DbgFlag) ){
			Debug = db;
			DbgFlag = dbf;
		} else {
			int tdb, tdbf;
			tdb = Debug;
			tdbf = DbgFlag;
			Debug = db;
			DbgFlag = dbf;
			if( Log_file_DYN ){
				tempfd = Checkwrite( Log_file_DYN, &statb,0,0,0);
				if( tempfd > 0 && tempfd != 2 ){
					dup2(tempfd,2);
					close(tempfd);
				}
				tempfd = -1;
			}
			Debug = tdb;
			DbgFlag = tdbf;
			LOGDEBUG("Receive_secure: socket fd %d", *sock);
			Dump_line_list("Receive_secure - input", &args);
		}
		DEBUGF(DRECV1)("Receive_secure: debug '%s', Debug %d, DbgFlag 0x%x",
			s, Debug, DbgFlag );
	}

	if( !(security = Fix_receive_auth(authtype, &info)) ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("unsupported authentication '%s'"), authtype );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}
	if( !security->server_receive ){
		plp_snprintf( error+1, sizeof(error)-1,
			_("no receive method supported for '%s'"), authtype );
		ack = ACK_FAIL;	/* no retry, don't send again */
		status = JFAIL;
		goto error;
	}


	if( jobsize ){
		double read_len;
		read_len = strtod(jobsize,0);

		DEBUGF(DRECV2)("Receive_secure: spooling_disabled %d",
			Sp_disabled(&Spool_control) );
		if( Sp_disabled(&Spool_control) ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("%s: spooling disabled"), Printer_DYN );
			ack = ACK_RETRY;	/* retry */
			status = JFAIL;
			goto error;
		}
		if( Max_job_size_DYN > 0 && (read_len+1023)/1024 > Max_job_size_DYN ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("%s: job size %0.0f is larger than %d K"),
				Printer_DYN, read_len, Max_job_size_DYN );
			ack = ACK_RETRY;
			status = JFAIL;
			goto error;
		} else if( !Check_space( read_len, Minfree_DYN, Spool_dir_DYN ) ){
			plp_snprintf( error+1, sizeof(error)-1,
				_("%s: insufficient file space"), Printer_DYN );
			ack = ACK_RETRY;
			status = JFAIL;
			goto error;
		}
	}

	tempfd = Make_temp_fd(&tempfile);
	close(tempfd); tempfd = -1;

	DEBUGF(DRECV1)("Receive_secure: sock %d, user '%s', jobsize '%s'",  
		*sock, user, jobsize );

	status = security->server_receive( sock, Send_job_rw_timeout_DYN,
		user, jobsize, from_server, authtype,
		&info,
		error+1, sizeof(error)-1,
		&header_info,
		security, tempfile, Do_secure_work);

 error:
	DEBUGF(DRECV1)("Receive_secure: status %d, ack %d, error '%s'",
		status, ack, error+1 );

	if( status ){
		if( ack == 0 ) ack = ACK_FAIL;
		error[0] = ack;
		DEBUGF(DRECV1)("Receive_secure: sending '%s'", error );
		(void)Link_send( ShortRemote_FQDN, sock,
			Send_query_rw_timeout_DYN, error, safestrlen(error), 0 );
		Errorcode = JFAIL;
	}

	Free_line_list( &args );
	Free_line_list( &header_info );
	Free_line_list( &info );

	close( *sock ); *sock = -1;
	Remove_tempfiles();

	if( status == 0 && jobsize ){
		/* start a new server */
		DEBUGF(DRECV1)("Receive_secure: starting server");
		if( Server_queue_name_DYN ){
			Do_queue_jobs( Server_queue_name_DYN, 0 );
		} else {
			Do_queue_jobs( Printer_DYN, 0 );
		}
	}
	cleanup(0);
}
예제 #8
0
static int Do_secure_work( char *jobsize, int from_server,
	char *tempfile, struct line_list *header_info )
{
	int n, len, linecount = 0, done = 0, fd, status = 0;
	char *s, *t;
	char buffer[SMALLBUFFER];
	char error[SMALLBUFFER];
	struct stat statb;

	error[0] = 0;
	if( (fd = Checkread(tempfile,&statb)) < 0 ){ 
		status = JFAIL;
		plp_snprintf( error, sizeof(error),
			"Do_secure_work: reopen of '%s' failed - %s",
				tempfile, Errormsg(errno));
		goto error;
	}

	buffer[0] = 0;
	n = 0;
	done = 0;
	linecount = 0;

	while( !done && n < (int)sizeof(buffer)-1
		&& (len = Read_fd_len_timeout( Send_query_rw_timeout_DYN, fd, buffer+n, sizeof(buffer)-1-n )) > 0 ){
		buffer[n+len] = 0;
		DEBUGF(DRECV1)("Do_secure_work: read %d - '%s'", len, buffer );
		while( !done && (s = safestrchr(buffer,'\n')) ){
			*s++ = 0;
			if( safestrlen(buffer) == 0 ){
				done = 1;
				break;
			}
			DEBUGF(DRECV1)("Do_secure_work: line [%d] '%s'", linecount, buffer );
			if( (t = strchr(buffer,'=')) ){
				*t++ = 0;
				Unescape(t);
				Set_str_value(header_info, buffer, t );
			} else {
				switch( linecount ){
					case 0:
						if( jobsize ){
							if( from_server ){
								Set_str_value(header_info,CLIENT,buffer);
							}
							done = 1;
						} else {
							Set_str_value(header_info,INPUT,buffer); break;
						}
						break;
					case 1:
						Set_str_value(header_info,CLIENT,buffer);
						done = 1;
						break;
				}
			}
			++linecount;
			memmove(buffer,s,safestrlen(s)+1);
			n = safestrlen(buffer);
		}
	}

	if( fd >= 0 ) close(fd); fd = -1;

	DEBUGFC(DRECV1)Dump_line_list("Do_secure_work - header", header_info );

	if( (status = Check_secure_perms( header_info, from_server, error, sizeof(error))) ){
		goto error;
	}
	DEBUGFC(DRECV1)Dump_line_list("Do_secure_work - header after check", header_info );


	buffer[0] = 0;
	if( jobsize ){
		if( (fd = Checkread(tempfile, &statb) ) < 0 ){
			status = JFAIL;
			plp_snprintf( error, sizeof(error),
				"Do_secure_work: reopen of '%s' for read failed - %s",
					tempfile, Errormsg(errno));
			goto error;
		}
		status = Scan_block_file( fd, error, sizeof(error), header_info );
		if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){
			status = JFAIL;
			plp_snprintf( error, sizeof(error),
				"Do_secure_work: reopen of '%s' for write failed - %s",
					tempfile, Errormsg(errno));
			goto error;
		}
	} else {
		if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){
			status = JFAIL;
			plp_snprintf( error, sizeof(error),
				"Do_secure_work: reopen of '%s' for write failed - %s",
					tempfile, Errormsg(errno));
			goto error;
		}
		if( (s = Find_str_value(header_info,INPUT)) ){
			Dispatch_input( &fd, s, "from secure link" );
		}
	}

 error:

	if( fd >= 0 ) close(fd); fd = -1;
	DEBUGF(DRECV1)("Do_secure_work: status %d, tempfile '%s', error '%s'",
		status, tempfile, error );
	if( error[0] ){
		DEBUGF(DRECV1)("Do_secure_work: updating tempfile '%s', error '%s'",
			tempfile, error );
		if( (fd = Checkwrite(tempfile,&statb,O_WRONLY|O_TRUNC,1,0)) < 0 ){
			Errorcode = JFAIL;
			logerr_die(LOG_INFO, "Do_secure_work: reopen of '%s' for write failed",
				tempfile );
		}
		Write_fd_str(fd,error);
		close(fd);
	}
	DEBUGF(DRECV1)("Do_secure_work: returning %d", status );
	return( status );
}
예제 #9
0
파일: errormsg.c 프로젝트: Distrotech/lprng
 static void log_backend (int kind, char *log_buf)
{
    char stamp_buf[2*SMALLBUFFER];
	int n;
	char *s;
	/* plp_block_mask omask; / **/
	int err = errno;

    /* plp_block_all_signals (&omask); / **/
	/* put the error message into the status file as well */
    /*
     * Now build up the state info: timestamp, hostname, argv[0], pid, etc.
     * Don't worry about efficiency here -- it shouldn't happen very often
     * (unless we're debugging).
     */

	stamp_buf[0] = 0;
	/* remove trailing \n */
	if( (s = strrchr(log_buf, '\n')) && cval(s+1) == 0 ){
		*s = 0;
	}


	if( Is_server || DEBUGL1 ){
		/* log stuff */
		if( (LOG_EMERG < LOG_INFO && kind <= LOG_INFO )
			|| ( LOG_EMERG > LOG_INFO && kind >= LOG_INFO )){
			setstatus( 0, "%s", log_buf );
			use_syslog(kind, log_buf);
		}
		n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
		(void) plp_snprintf( s, n, "%s", Time_str(0,0) );
		if (ShortHost_FQDN ) {
			n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
			(void) plp_snprintf( s, n, " %s", ShortHost_FQDN );
		}
		if(Debug || DbgFlag){
			n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
			(void) plp_snprintf(s, n, " [%ld]", (long)getpid());
			n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
			if(Name) (void) plp_snprintf(s, n, " %s", Name);
			n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
			(void) plp_snprintf(s, n, " %s", putlogmsg(kind) );
		}
		n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
		(void) plp_snprintf(s, n, " %s", log_buf );
	} else {
		(void) plp_snprintf(stamp_buf, sizeof(stamp_buf), "%s", log_buf );
	}

	if( safestrlen(stamp_buf) > (int)sizeof(stamp_buf) - 8 ){
		stamp_buf[sizeof(stamp_buf)-8] = 0;
		strcpy(stamp_buf+safestrlen(stamp_buf),"...");
	}
	n = safestrlen(stamp_buf); s = stamp_buf+n; n = sizeof(stamp_buf)-n;
	(void) plp_snprintf(s, n, "\n" );


    /* use writes here: on HP/UX, using f p rintf really screws up. */
	/* if stdout or stderr is dead, you have big problems! */

	Write_fd_str( 2, stamp_buf );

    /* plp_unblock_all_signals ( &omask ); / **/
	errno = err;
}
예제 #10
0
파일: monitor.c 프로젝트: Einheri/wl500g
int main(int argc, char *argv[] )
{
	int n, i, c, err, max_port = 0;
	char *portname, *s;
	struct servent *servent;
	struct info *in;

	prog = argv[0];
	Opterr = 1;
	while( (n = Getopt(argc, argv, "dut")) != EOF ){
		switch(n){
		default:  usage(); break;
		case 'u': use_udp = !use_udp; break;
		case 't': use_tcp = !use_tcp; break;
		case 'd': debug = 1; break;
		}
	}
	i = argc - Optind;
	if( i > 1 ) usage();
	if( i == 1 ){
		portname = argv[Optind];
		n = atoi( portname );
		if( n <= 0 ){
			servent = getservbyname( portname, "udp" );
			if( servent ){
				n = ntohs( servent->s_port );
			}
		}
		if( n <= 0 ){
			FPRINTF( STDERR, "udp_open: bad port number '%s'\n",portname );
			usage();
		}
		port_num = n;
	}

	if( !use_tcp && !use_udp ) use_udp = 1;
	if( debug ){
		FPRINTF(STDERR,"monitor: udp %d, tcp %d, port %d\n",
			use_udp, use_tcp, port_num );
	}

	max_port = 0;
	FD_ZERO( &readfds );
	if( use_udp && (udp_fd = udp_open( port_num )) >= 0){
		if( debug ) FPRINTF(STDERR,"monitor: udp port %d\n", udp_fd );
		FD_SET(udp_fd, &readfds);
		if( udp_fd >= max_port ) max_port = udp_fd+1;
	}
	if( use_tcp && (tcp_fd = tcp_open( port_num )) >= 0){
		if( debug ) FPRINTF(STDERR,"monitor: tcp port %d\n", tcp_fd );
		FD_SET(tcp_fd, &readfds);
		if( tcp_fd >= max_port ) max_port = tcp_fd+1;
	}
	if( debug ){
		FPRINTF(STDERR,"monitor: max_port %d\n", max_port );
		for( i = 0; i < max_port; ++i ){
			if( FD_ISSET(i, &readfds) ){
				FPRINTF(STDERR,"monitor: initial on %d\n", i );
			}
		}
	}


	while(1){
		FD_ZERO( &testfds );
		for( i = 0; i < max_port; ++i ){
			if( FD_ISSET(i, &readfds) ){
				if( debug ) FPRINTF(STDERR,"monitor: waiting on %d\n", i );
				FD_SET(i, &testfds);
			}
		}
		if( debug ) FPRINTF(STDERR,"monitor: starting wait, max %d\n", i );
		n = select( i,
			FD_SET_FIX((fd_set *))&testfds,
			FD_SET_FIX((fd_set *))0, FD_SET_FIX((fd_set *))0,
			(struct timeval *)0 );
		err = errno;
		if( debug ) FPRINTF(STDERR,"monitor: select returned %d\n", n );
		if( n < 0 ){
			FPRINTF( STDERR, "select error - %s\n", Errormsg(errno) );
			if( err != EINTR ) break;
		}
		if( n > 0 ) for( i = 0; i < max_port; ++i ){
			if( FD_ISSET(i, &testfds) ){
				if( debug ) FPRINTF(STDERR,"monitor: input on %d\n", i );
				if( i == tcp_fd ){
#if defined(HAVE_SOCKLEN_T)
					socklen_t len;
#else
					int len;
#endif
					struct sockaddr_in sinaddr;
					len = sizeof( sinaddr );
					i = accept( tcp_fd, (struct sockaddr *)&sinaddr, &len );
					if( i < 0 ){
						FPRINTF( STDERR, "accept error - %s\n",
							Errormsg(errno) );
						continue;
					}
					FPRINTF( STDOUT, "connection from %s\n",
						inet_ntoa( sinaddr.sin_addr ) );
					if( i >= max_port ) max_port = i+1;
					FD_SET(i, &readfds);
				} else {
					c = read( i, buffer, sizeof(buffer)-1 );
					if( c == 0 ){
						/* closed connection */
						FPRINTF(STDOUT, "closed connection %d\n", i );
						close( i );
						FD_CLR(i, &readfds );
						Clear_buffer(i);
					} else if( c > 0 ){
						buffer[c] = 0;
						if(debug)FPRINTF( STDOUT, "recv port %d: %s\n", i, buffer );
						Add_buffer(i);
						in = Save_outbuf_len( i, buffer, c );
						while( (s = safestrchr(in->buffer,'\n')) ){
							*s++ = 0;
							Decode(in->buffer);
							memmove(in->buffer,s, safestrlen(s)+1 );
							in->len = safestrlen(in->buffer);
						}
					} else {
						FPRINTF( STDERR, "read error - %s\n",
							Errormsg(errno) );
						close( i );
						FD_CLR(i, &readfds );
					}
				}
			}
		}
	}
	return(0);
}