OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [libnetworking/] [pppd/] [main.c] - Rev 307

Go to most recent revision | Compare with Previous | Blame | View Log

/*
 * main.c - Point-to-Point Protocol main module
 *
 * Copyright (c) 1989 Carnegie Mellon University.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that the above copyright notice and this paragraph are
 * duplicated in all such forms and that any documentation,
 * advertising materials, and other materials related to such
 * distribution and use acknowledge that the software was developed
 * by Carnegie Mellon University.  The name of the
 * University may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */
 
/*#ifndef lint
/* static char rcsid[] = "$Id: main.c,v 1.2 2001-09-27 12:01:57 chris Exp $"; */
#endif
*/
#include <stdio.h>
#include <ctype.h>
/* #include <stdlib.h> */
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <netdb.h>
#include <pwd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <rtems/rtems/tasks.h>
#include <sys/types.h>
#include <netinet/in.h>
 
/* #include <stbconfig.h> */
#include "pppd.h"
#include "magic.h"
#include "fsm.h"
#include "lcp.h"
#include "ipcp.h"
#include "upap.h"
#include "chap.h"
#include "ccp.h"
#include "pathnames.h"
#include "patchlevel.h"
 
#ifdef CBCP_SUPPORT
#include "cbcp.h"
#endif
 
#if defined(SUNOS4)
extern char *strerror();
#endif
 
#ifdef IPX_CHANGE
#include "ipxcp.h"
#endif							/* IPX_CHANGE */
#ifdef AT_CHANGE
#include "atcp.h"
#endif
 
void SetStatusInfo(int state, char * text, int res);
 
/* interface vars */
char ifname[32];				/* Interface name */
int interfunit;					/* Interface unit number */
 
char *progname;					/* Name of this program */
char hostname[MAXNAMELEN] = "infotel";	/* Our hostname */
static char default_devnam[MAXPATHLEN];		/* name of default device */
/*static pid_t pid;	*/			/* Our pid */
static uid_t uid;				/* Our real user-id */
static int conn_running;		/* we have a [dis]connector running */
 
int ttyfd = -1;					/* Serial port file descriptor */
mode_t tty_mode = -1;			/* Original access permissions to tty */
int baud_rate;					/* Actual bits/second for serial device */
int hungup;						/* terminal has been hung up */
int privileged;					/* we're running as real uid root */
int need_holdoff;				/* need holdoff period before restarting */
int detached;					/* have detached from terminal */
 
int phase;						/* where the link is at */
int kill_link;
int open_ccp_flag;
 
char **script_env;				/* Env. variable values for scripts */
int s_env_nalloc;				/* # words avail at script_env */
 
u_char outpacket_buf[PPP_MRU + PPP_HDRLEN];		/* buffer for outgoing packet */
u_char inpacket_buf[PPP_MRU + PPP_HDRLEN];	/* buffer for incoming packet */
 
 
 
char *no_ppp_msg = "lack of PPP\n";
 
/* Prototypes for procedures local to this file. */
static void cleanup(void);
static void create_pidfile __P((void));
static void close_tty __P((void));
static void get_input __P((void));
static void calltimeout __P((void));
static struct timeval *timeleft __P((struct timeval *));
static void holdoff_end __P((void *));
static int device_script __P((char *[], int, int));
static void reap_kids __P((void));
static void pr_log __P((void *, char *,...));
 
extern char *ttyname __P((int));
extern char *getlogin __P((void));
int main __P((int, char *[]));
 
 
 
 
 
/*
 * PPP Data Link Layer "protocol" table.
 * One entry per supported protocol.
 * The last entry must be NULL.
 */
struct protent *protocols[] =
{
	&lcp_protent,
	&pap_protent,
	&chap_protent,
#ifdef CBCP_SUPPORT
	&cbcp_protent,
#endif
	&ipcp_protent,
	&ccp_protent,
#ifdef IPX_CHANGE
	&ipxcp_protent,
#endif
#ifdef AT_CHANGE
	&atcp_protent,
#endif
	NULL
};
 
extern int connect_stb();
 
 
extern int disconnect_stb();
 
 
extern struct in_addr rtems_bsdnet_nameserver[];
extern int rtems_bsdnet_nameserver_count;
extern int __res_init(void);
 
int pppdmain(argc, argv)
int argc;
char *argv[];
{
	int i;
	struct timeval timo;
	struct protent *protp;
	struct stat statbuf;
    	char t[100];
 
 
	phase = PHASE_INITIALIZE;
 
	strcpy(default_devnam, "/dev/modem");
	strcpy(devnam, "/dev/modem");
 
	script_env = NULL;
 
/*    if (gethostname(hostname, MAXNAMELEN) < 0 ) {
   die(1);
   }
 */
	hostname[MAXNAMELEN - 1] = 0;
 
	uid = 0;
	privileged = uid == 0;
 
	/*
	 * Initialize to the standard option set, then parse, in order,
	 * the system options file, the user's options file,
	 * the tty's options file, and the command line arguments.
	 */
	for (i = 0; (protp = protocols[i]) != NULL; ++i)
		(*protp->init) (0);
 
 
 
	if (!ppp_available()) {
		exit(1);
	}
	/*
	 * Check that the options given are valid and consistent.
	 */
	sys_check_options();
	auth_check_options();
	for (i = 0; (protp = protocols[i]) != NULL; ++i)
		if (protp->check_options != NULL)
			(*protp->check_options) ();
 
	/*
	 * If the user has specified the default device name explicitly,
	 * pretend they hadn't.
	 */
	if (!default_device && strcmp(devnam, default_devnam) == 0)
		default_device = 1;
	if (default_device)
		nodetach = 1;
 
	/*
	 * Initialize system-dependent stuff and magic number package.
	 */
	sys_init();
	magic_init();
 
	/*
	 * Detach ourselves from the terminal, if required,
	 * and identify who is running us.
	 */
 
/*
	syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d",
	     VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid);
*/
 
 
	for (;;) {
 
/* !!! here should be done some kind of synchronization - I did it following way ... */
/* GlobalSystemStatus is set of different things shared between different tasks ... */
#if 0
/* XXX PPPConfiguration */
	GlobalSystemStatus * volatile stat;
	stat=LockSTBSystemParam();
	stat->ConnectionStatus = NotConnected;
	UnlockSTBSystemParam();
#endif
 
 
		while (1) {
			rtems_event_set events;
			int status;
 
#if 0
/* XXX PPPConfiguration */
			stat=LockSTBSystemParam();
			status=stat->WantConnection;
			UnlockSTBSystemParam();
 
			if (status == Connect) break;
#endif
			rtems_event_receive(RTEMS_EVENT_1, RTEMS_WAIT | RTEMS_EVENT_ANY, RTEMS_NO_TIMEOUT, &events);
		}
#if 0
/* XXX PPPConfiguration */
	stat=LockSTBSystemParam();
/* 	stat->WantConnection=DontConnect; */
	stat->ConnectionStatus = Connecting;
 
/* Here you can change default nameserver ... */
	rtems_bsdnet_nameserver[0].s_addr=inet_addr(stat->DNS);
	rtems_bsdnet_nameserver_count=1;
	UnlockSTBSystemParam();
#endif
/* initialize DNS services here */
	 SetStatusInfo(0, "Connecting...",0);
 
	__res_init();
		/*
		 * Open the serial device and set it up to be the ppp interface.
		 * First we open it in non-blocking mode so we can set the
		 * various termios flags appropriately.  If we aren't dialling
		 * out and we want to use the modem lines, we reopen it later
		 * in order to wait for the carrier detect signal from the modem.
		 */
		while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0)) < 0) {
			if (errno != EINTR)
				syslog(LOG_ERR, "Failed to open %s: %m", devnam);
 
			if (!persist || errno != EINTR)
				goto fail;
		}
 
		hungup = 0;
		kill_link = 0;
 
		/*
		 * Do the equivalent of `mesg n' to stop broadcast messages.
		 */
		tty_mode = statbuf.st_mode;
 
		/* run connection script */
		/*
		 * Set line speed, flow control, etc.
		 * On most systems we set CLOCAL for now so that we can talk
		 * to the modem before carrier comes up.  But this has the
		 * side effect that we might miss it if CD drops before we
		 * get to clear CLOCAL below.  On systems where we can talk
		 * successfully to the modem with CLOCAL clear and CD down,
		 * we can clear CLOCAL at this point.
		 */
		set_up_tty(ttyfd, 1);
 
		/* drop dtr to hang up in case modem is off hook */
		setdtr(ttyfd, FALSE);
		sleep(1);
		setdtr(ttyfd, TRUE);
	    {
/* Make a call ... */
#if 0
/* XXX PPPConfiguration */
	    	char t[100];
			stat=LockSTBSystemParam();
			sprintf(t,"Dzwoniê pod numer %s ...",stat->Phone_Number);
			UnlockSTBSystemParam();	    	
#endif
	    	SetStatusInfo(0, t,0);
	    }
 
 
		if ((i=connect_script(ttyfd)) >0) {
/* here go error messages ... */
		static char *error_msgs[]={ "Bad script", "IO Error"
		 	"Timeout", "Busy", "No dialtone", "No carrier",
			"No answer", "No answer from server" };
			setdtr(ttyfd, FALSE);
	    	sprintf(t,"Communication error: %s",error_msgs[i-1]);
		syslog(LOG_ERR, "Connect script failed");
	    	SetStatusInfo(0, t,1);
			goto fail;
		}
 
		else
		if (i<0)
		{
	    	char t[100];
			sprintf(t,"£¹czenie z Internetem z prêdkosci¹ %d baud...",-i);
		    SetStatusInfo(0, t,0);
		}
		else		
			    SetStatusInfo(0, "£¹czenie z Internetem...",0);
		syslog(LOG_INFO, "Serial connection established.");
 
		sleep(1);				/* give it time to set up its terminal */
 
		/* set line speed, flow control, etc.; clear CLOCAL if modem option */
		set_up_tty(ttyfd, 0);
 
		/* reopen tty if necessary to wait for carrier */
 
		/* run welcome script, if any */
/*  if (welcomer && welcomer[0]) {
   if (device_script(welcomer, 21, ttyfd) < 0)
   syslog(LOG_WARNING, "Welcome script failed");
   }
 */
		/* set up the serial device as a ppp interface */
		establish_ppp(ttyfd);
 
/*  syslog(LOG_INFO, "Using interface ppp%d", interfunit);  */
		(void) sprintf(ifname, "ppp%d", interfunit);
 
		/*
		 * Start opening the connection and wait for
		 * incoming events (reply, timeout, etc.).
		 */
/*   syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); */
 
		rtems_bsdnet_semaphore_obtain();
 
		lcp_lowerup(0);
		lcp_open(0);			/* Start protocol */
 
		rtems_bsdnet_semaphore_release();
        SetStatusInfo(0, "Po³¹czenie z Internetem nawi¹zane.",1);
 
		for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD;) {
			wait_input(timeleft(&timo));
			calltimeout();
			get_input();
#if 0
/* XXX PPPConfiguration */
			stat=LockSTBSystemParam();
			if (stat->WantConnection==DontConnect) {
				stat->ConnectionStatus = NotConnected;
			    SetStatusInfo(0, "Roz³¹czam siê ...",0);
				lcp_close(0, "");
				kill_link = 0;
			}
			UnlockSTBSystemParam();
#endif
			if (open_ccp_flag) {
				if (phase == PHASE_NETWORK) {
					ccp_fsm[0].flags = OPT_RESTART;		/* clears OPT_SILENT */
					(*ccp_protent.open) (0);
				}
				open_ccp_flag = 0;
			}
		}
		/*
		 * If we may want to bring the link up again, transfer
		 * the ppp unit back to the loopback.  Set the
		 * real serial device back to its normal mode of operation.
		 */
		clean_check();
		disestablish_ppp(ttyfd);
	    SetStatusInfo(0, "Po³¹czenie z Internetem zerwane.",1);
 
		/*
		 * Run disconnector script, if requested.
		 * XXX we may not be able to do this if the line has hung up!
		 */
/*  if (disconnector && !hungup) {
   set_up_tty(ttyfd, 1);
   if (device_script(disconnector, ttyfd, ttyfd) < 0) {
   syslog(LOG_WARNING, "disconnect script failed");
   } else {
   syslog(LOG_INFO, "Serial link disconnected.");
   }
   }
 */
	  fail:
#if 0
/* XXX PPPConfiguration */
		stat=LockSTBSystemParam();
		stat->ConnectionStatus = NotConnected;
		stat->WantConnection=DontConnect;
		UnlockSTBSystemParam();
#endif
		if (ttyfd >= 0)
			close_tty();
 
 
 
	}
 
	return 0;
}
 
/*
 * detach - detach us from the controlling terminal.
 */
void detach()
{
}
 
/*
 * holdoff_end - called via a timeout when the holdoff period ends.
 */
 
static void holdoff_end(arg)
void *arg;
{
	phase = PHASE_DORMANT;
}
 
/*
 * get_input - called when incoming data is available.
 */
static void get_input()
{
	int len, i;
	u_char *p;
	u_short protocol;
	struct protent *protp;
 
	p = inpacket_buf;			/* point to beginning of packet buffer */
 
	len = read_packet(inpacket_buf);
	if (len < 0)
		return;
 
	if (len == 0) {
#if 0
/* XXX PPPConfiguration */
		GlobalSystemStatus * volatile stat;
#endif
/*   syslog(LOG_NOTICE, "Modem hangup"); */
		hungup = 1;
#if 0
/* XXX PPPConfiguration */
		stat=LockSTBSystemParam();
		stat->ConnectionStatus = NotConnected;
		UnlockSTBSystemParam();
#endif
 
		lcp_lowerdown(0);		/* serial link is no longer available */
		link_terminated(0);
		return;
	}
/*	if ((debug))
		log_packet(p, len, "rcvd ", LOG_DEBUG);
*/
 
	if (len < PPP_HDRLEN) {
/*
		if (debug)
			MAINDEBUG((LOG_INFO, "io(): Received short packet."));
*/
		return;
	}
/* We need to modify internal network structures here */
	rtems_bsdnet_semaphore_obtain();
 
	p += 2;						/* Skip address and control */
	GETSHORT(protocol, p);
	len -= PPP_HDRLEN;
 
	/*
	 * Toss all non-LCP packets unless LCP is OPEN.
	 */
	if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
		MAINDEBUG((LOG_INFO,
			   "get_input: Received non-LCP packet when LCP not open."));
		rtems_bsdnet_semaphore_release();
		return;
	}
	/*
	 * Until we get past the authentication phase, toss all packets
	 * except LCP, LQR and authentication packets.
	 */
	if (phase <= PHASE_AUTHENTICATE
		&& !(protocol == PPP_LCP || protocol == PPP_LQR
			 || protocol == PPP_PAP || protocol == PPP_CHAP)) {
 
		rtems_bsdnet_semaphore_release();
		return;
	}
	/*
	 * Upcall the proper protocol input routine.
	 */
	for (i = 0; (protp = protocols[i]) != NULL; ++i) {
		if (protp->protocol == protocol && protp->enabled_flag) {
			(*protp->input) (0, p, len);
			rtems_bsdnet_semaphore_release();
			return;
		}
		if (protocol == (protp->protocol & ~0x8000) && protp->enabled_flag
			&& protp->datainput != NULL) {
			(*protp->datainput) (0, p, len);
			rtems_bsdnet_semaphore_release();
			return;
		}
	}
 
	lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN);
	rtems_bsdnet_semaphore_release();
}
 
 
/*
 * quit - Clean up state and exit (with an error indication).
 */
void quit()
{
	die(1);
}
 
/*
 * die - like quit, except we can specify an exit status.
 */
void die(status)
int status;
{
	cleanup();
}
 
/*
 * cleanup - restore anything which needs to be restored before we exit
 */
/* ARGSUSED */
static void cleanup()
{
	sys_cleanup();
 
	if (ttyfd >= 0)
		close_tty();
 
}
 
/*
 * close_tty - restore the terminal device and close it.
 */
static void close_tty()
{
	disestablish_ppp(ttyfd);
 
	/* drop dtr to hang up */
	setdtr(ttyfd, FALSE);
	/*
	 * This sleep is in case the serial port has CLOCAL set by default,
	 * and consequently will reassert DTR when we close the device.
	 */
	sleep(1);
 
	restore_tty(ttyfd);
	close(ttyfd);
	ttyfd = -1;
}
 
 
struct callout {
	struct timeval c_time;
	void *c_arg;
	void (*c_func) __P((void *));
	struct callout *c_next;
};
 
static struct callout *callout = NULL;
static struct timeval timenow;
 
/*
 * timeout - Schedule a timeout.
 *
 * Note that this timeout takes the number of seconds, NOT hz (as in
 * the kernel).
 */
void my_timeout(func, arg, time)
void (*func) __P((void *));
void *arg;
int time;
{
	struct callout *newp, *p, **pp;
 
	MAINDEBUG((LOG_DEBUG, "Timeout %lx:%lx in %d seconds.",
			   (long) func, (long) arg, time));
	/*
	 * Allocate timeout.
	 */
	if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) {
/*  syslog(LOG_ERR, "Out of memory in timeout()!"); */
		die(1);
	}
	newp->c_arg = arg;
	newp->c_func = func;
	gettimeofday(&timenow, NULL);
	newp->c_time.tv_sec = timenow.tv_sec + time;
	newp->c_time.tv_usec = timenow.tv_usec;
	/*
	 * Find correct place and link it in.
	 */
	for (pp = &callout; (p = *pp); pp = &p->c_next)
		if (newp->c_time.tv_sec < p->c_time.tv_sec
			|| (newp->c_time.tv_sec == p->c_time.tv_sec
				&& newp->c_time.tv_usec < p->c_time.tv_sec))
			break;
	newp->c_next = p;
	*pp = newp;
}
 
/*
 * untimeout - Unschedule a timeout.
 */
 
void untimeout(func, arg)
void (*func) __P((void *));
void *arg;
{
	struct callout **copp, *freep;
 
	MAINDEBUG((LOG_DEBUG, "Untimeout %lx:%lx.", (long) func, (long) arg));
 
	for (copp = &callout; (freep = *copp); copp = &freep->c_next)
		if (freep->c_func == func && freep->c_arg == arg) {
			*copp = freep->c_next;
			(void) free((char *) freep);
			break;
		}
}
 
 
/*
 * calltimeout - Call any timeout routines which are now due.
 */
static void calltimeout()
{
	struct callout *p;
 
	while (callout != NULL) {
		p = callout;
 
		if (gettimeofday(&timenow, NULL) < 0) {
			die(1);
		}
		if (!(p->c_time.tv_sec < timenow.tv_sec
			  || (p->c_time.tv_sec == timenow.tv_sec
				  && p->c_time.tv_usec <= timenow.tv_usec)))
			break;				/* no, it's not time yet */
 
		callout = p->c_next;
		(*p->c_func) (p->c_arg);
 
		free((char *) p);
	}
}
 
 
/*
 * timeleft - return the length of time until the next timeout is due.
 */
static struct timeval *
 timeleft(tvp)
struct timeval *tvp;
{
	if (callout == NULL)
		return NULL;
 
	gettimeofday(&timenow, NULL);
	tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec;
	tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec;
	if (tvp->tv_usec < 0) {
		tvp->tv_usec += 1000000;
		tvp->tv_sec -= 1;
	}
	if (tvp->tv_sec < 0)
		tvp->tv_sec = tvp->tv_usec = 0;
 
	return tvp;
}
 
 
/*
 * term - Catch SIGTERM signal and SIGINT signal (^C/del).
 *
 * Indicates that we should initiate a graceful disconnect and exit.
 */
static void term(sig)
int sig;
{
	/*    persist = 0; *//* don't try to restart */
	kill_link = 1;
}
 
static int input_fd, output_fd;
#include <rtems/rtems/tasks.h>
 
 
 
extern int modem_fd;
int connect_script(int fd)
{
	int status;
	char program[256];
#if 0
/* XXX PPPConfiguration */
	GlobalSystemStatus * volatile stat;
#endif
/* Connect scripts are almost the same as in Linux Chat ... */
	static char *scripts[] =
	{
		"TIMEOUT@5@@\rAT@OK-+++\\c-OK@ATH0@TIMEOUT@90@OK@ATDT%s@CONNECT@",
		"TIMEOUT@5@@\rAT@OK-+++\\c-OK@ATH0@TIMEOUT@90@OK@ATDT%s@CONNECT@@ppp@@Username:@%s@Password:@%s@"
	};
	modem_fd = fd;
#if 0
/* XXX PPPConfiguration */
	stat=LockSTBSystemParam();	
	if (strcmp("",stat->PPP_User))
	{
		stat->provider=Poland_TPSA;
	}
	else
		stat->provider=DumbLogin;
	switch (stat->provider) {
	case Poland_TPSA:
		sprintf(program, scripts[1], stat->Phone_Number, stat->PPP_User, stat->PPP_Password);
		break;
	default:
		sprintf(program, scripts[0], stat->Phone_Number);
 
	}
	UnlockSTBSystemParam();
#endif
	conn_running = 0;
 
	return chatmain(program);
}
 
 
/*
 * run-program - execute a program with given arguments,
 * but don't wait for it.
 * If the program can't be executed, logs an error unless
 * must_exist is 0 and the program file doesn't exist.
 */
int run_program(prog, args, must_exist)
char *prog;
char **args;
int must_exist;
{
 
	return 0;
}
 
 
/*
 * reap_kids - get status from any dead child processes,
 * and log a message for abnormal terminations.
 */
static void reap_kids()
{
}
 
 
/*
 * log_packet - format a packet and log it.
 */
 
char line[256];
char *linep;
 
/*#define log_packet(p, len, prefix, level) */
void log_packet(p, len, prefix, level)
u_char *p;
int len;
char *prefix;
int level;
{
	strcpy(line, prefix);
	linep = line + strlen(line);
/*	format_packet(p, len, pr_log, NULL); */
/*    if (linep != line)
   syslog(level, "%s", line);
 */
}
 
/*
 * format_packet - make a readable representation of a packet,
 * calling `printer(arg, format, ...)' to output it.
 */
/*#define format_packet(p, len, printer, arg) */
 
void format_packet(p, len, printer, arg)
u_char *p;
int len;
void (*printer) __P((void *, char *,...));
void *arg;
{
/*
	int i, n;
	u_short proto;
	struct protent *protp;
 
	if (len >= PPP_HDRLEN && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
		p += 2;
		GETSHORT(proto, p);
		len -= PPP_HDRLEN;
		for (i = 0; (protp = protocols[i]) != NULL; ++i)
			if (proto == protp->protocol)
				break;
		if (protp != NULL) {
			printer(arg, "[%s", protp->name);
			n = (*protp->printpkt) (p, len, printer, arg);
			printer(arg, "]");
			p += n;
			len -= n;
		} else {
			printer(arg, "[proto=0x%x]", proto);
		}
	}
*/
/*    for (; len > 0; --len) {
   GETCHAR(x, p);
   printer(arg, " %.2x", x);
   }
 */
}
 
 
 
static void
pr_log __V((void *arg, char *fmt,...))
{
	int n;
	va_list pvar;
	char buf[256];
 
#if __STDC__
	va_start(pvar, fmt);
#else
	void *arg;
	char *fmt;
	va_start(pvar);
	arg = va_arg(pvar, void *);
	fmt = va_arg(pvar, char *);
#endif
 
	n = vfmtmsg(buf, sizeof(buf), fmt, pvar);
	va_end(pvar);
 
	if (linep + n + 1 > line + sizeof(line)) {
/*  syslog(LOG_DEBUG, "%s", line); */
		linep = line;
	}
	strcpy(linep, buf);
	linep += n;
}
 
/*
 * print_string - print a readable representation of a string using
 * printer.
 */
/*#define print_string(p, len, printer, arg) */
 
void print_string(p, len, printer, arg)
char *p;
int len;
void (*printer) __P((void *, char *,...));
void *arg;
{
	int c;
 
	printer(arg, "\"");
	for (; len > 0; --len) {
		c = *p++;
		if (' ' <= c && c <= '~') {
			if (c == '\\' || c == '"')
				printer(arg, "\\");
			printer(arg, "%c", c);
		} else {
			switch (c) {
			case '\n':
				printer(arg, "\\n");
				break;
			case '\r':
				printer(arg, "\\r");
				break;
			case '\t':
				printer(arg, "\\t");
				break;
			default:
				printer(arg, "\\%.3o", c);
			}
		}
	}
	printer(arg, "\"");
}
 
 
/*
 * novm - log an error message saying we ran out of memory, and die.
 */
void novm(msg)
char *msg;
{
/*    syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg);
 */ die(1);
}
 
/*
 * fmtmsg - format a message into a buffer.  Like sprintf except we
 * also specify the length of the output buffer, and we handle
 * %r (recursive format), %m (error message) and %I (IP address) formats.
 * Doesn't do floating-point formats.
 * Returns the number of chars put into buf.
 */
int
fmtmsg __V((char *buf, int buflen, char *fmt,...))
{
	va_list args;
	int n;
 
#if __STDC__
	va_start(args, fmt);
#else
	char *buf;
	int buflen;
	char *fmt;
	va_start(args);
	buf = va_arg(args, char *);
	buflen = va_arg(args, int);
	fmt = va_arg(args, char *);
#endif
	n = vfmtmsg(buf, buflen, fmt, args);
	va_end(args);
	return n;
}
 
/*
 * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args.
 */
#define OUTCHAR(c)	(buflen > 0? (--buflen, *buf++ = (c)): 0)
/*#define vfmtmsg(buf, buflen, fmt, args) */
 
int vfmtmsg(buf, buflen, fmt, args)
char *buf;
int buflen;
char *fmt;
va_list args;
{
/*    int c, i, n;
   int width, prec, fillch;
   int base, len, neg, quoted;
   unsigned long val = 0;
   char *str, *f, *buf0;
   unsigned char *p;
   char num[32];
   time_t t;
   static char hexchars[] = "0123456789abcdef";
 
   buf0 = buf;
   --buflen;
   while (buflen > 0) {
   for (f = fmt; *f != '%' && *f != 0; ++f)
   ;
   if (f > fmt) {
   len = f - fmt;
   if (len > buflen)
   len = buflen;
   memcpy(buf, fmt, len);
   buf += len;
   buflen -= len;
   fmt = f;
   }
   if (*fmt == 0)
   break;
   c = *++fmt;
   width = prec = 0;
   fillch = ' ';
   if (c == '0') {
   fillch = '0';
   c = *++fmt;
   }
   if (c == '*') {
   width = va_arg(args, int);
   c = *++fmt;
   } else {
   while (isdigit(c)) {
   width = width * 10 + c - '0';
   c = *++fmt;
   }
   }
   if (c == '.') {
   c = *++fmt;
   if (c == '*') {
   prec = va_arg(args, int);
   c = *++fmt;
   } else {
   while (isdigit(c)) {
   prec = prec * 10 + c - '0';
   c = *++fmt;
   }
   }
   }
   str = 0;
   base = 0;
   neg = 0;
   ++fmt;
   switch (c) {
   case 'd':
   i = va_arg(args, int);
   if (i < 0) {
   neg = 1;
   val = -i;
   } else
   val = i;
   base = 10;
   break;
   case 'o':
   val = va_arg(args, unsigned int);
   base = 8;
   break;
   case 'x':
   val = va_arg(args, unsigned int);
   base = 16;
   break;
   case 'p':
   val = (unsigned long) va_arg(args, void *);
   base = 16;
   neg = 2;
   break;
   case 's':
   str = va_arg(args, char *);
   break;
   case 'c':
   num[0] = va_arg(args, int);
   num[1] = 0;
   str = num;
   break;
   case 'm':
   str = strerror(errno);
   break;
   case 'I':
   str = ip_ntoa(va_arg(args, u_int32_t));
   break;
   case 'r':
   f = va_arg(args, char *);
   #ifndef __powerpc__
   n = vfmtmsg(buf, buflen + 1, f, va_arg(args, va_list));
   #else
 
   n = vfmtmsg(buf, buflen + 1, f, va_arg(args, void *));
   #endif
   buf += n;
   buflen -= n;
   continue;
   case 't':
   break;
   case 'v':         
   case 'q':     
   quoted = c == 'q';
   p = va_arg(args, unsigned char *);
   if (fillch == '0' && prec > 0) {
   n = prec;
   } else {
   n = strlen((char *)p);
   if (prec > 0 && prec < n)
   n = prec;
   }
   while (n > 0 && buflen > 0) {
   c = *p++;
   --n;
   if (!quoted && c >= 0x80) {
   OUTCHAR('M');
   OUTCHAR('-');
   c -= 0x80;
   }
   if (quoted && (c == '"' || c == '\\'))
   OUTCHAR('\\');
   if (c < 0x20 || (0x7f <= c && c < 0xa0)) {
   if (quoted) {
   OUTCHAR('\\');
   switch (c) {
   case '\t':   OUTCHAR('t');   break;
   case '\n':   OUTCHAR('n');   break;
   case '\b':   OUTCHAR('b');   break;
   case '\f':   OUTCHAR('f');   break;
   default:
   OUTCHAR('x');
   OUTCHAR(hexchars[c >> 4]);
   OUTCHAR(hexchars[c & 0xf]);
   }
   } else {
   if (c == '\t')
   OUTCHAR(c);
   else {
   OUTCHAR('^');
   OUTCHAR(c ^ 0x40);
   }
   }
   } else
   OUTCHAR(c);
   }
   continue;
   default:
   *buf++ = '%';
   if (c != '%')
   --fmt;       
   --buflen;
   continue;
   }
   if (base != 0) {
   str = num + sizeof(num);
   *--str = 0;
   while (str > num + neg) {
   *--str = hexchars[val % base];
   val = val / base;
   if (--prec <= 0 && val == 0)
   break;
   }
   switch (neg) {
   case 1:
   *--str = '-';
   break;
   case 2:
   *--str = 'x';
   *--str = '0';
   break;
   }
   len = num + sizeof(num) - 1 - str;
   } else {
   len = strlen(str);
   if (prec > 0 && len > prec)
   len = prec;
   }
   if (width > 0) {
   if (width > buflen)
   width = buflen;
   if ((n = width - len) > 0) {
   buflen -= n;
   for (; n > 0; --n)
   *buf++ = fillch;
   }
   }
   if (len > buflen)
   len = buflen;
   memcpy(buf, str, len);
   buf += len;
   buflen -= len;
   }
   *buf = 0;
   return buf - buf0;
 */
	return 0;
}
 
 
/*
 * script_setenv - set an environment variable value to be used
 * for scripts that we run (e.g. ip-up, auth-up, etc.)
 */
#define script_setenv(var, value)
/*
   void
   script_setenv(var, value)
   char *var, *value;
   {
   int vl = strlen(var);
   int i;
   char *p, *newstring;
 
   newstring = (char *) malloc(vl + strlen(value) + 2);
   if (newstring == 0)
   return;
   strcpy(newstring, var);
   newstring[vl] = '=';
   strcpy(newstring+vl+1, value);
 
   if (script_env != 0) {
   for (i = 0; (p = script_env[i]) != 0; ++i) {
   if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
   free(p);
   script_env[i] = newstring;
   return;
   }
   }
   } else {
   i = 0;
   script_env = (char **) malloc(16 * sizeof(char *));
   if (script_env == 0)
   return;
   s_env_nalloc = 16;
   }
 
   if (i + 1 >= s_env_nalloc) {
   int new_n = i + 17;
   char **newenv = (char **) realloc((void *)script_env,
   new_n * sizeof(char *));
   if (newenv == 0)
   return;
   script_env = newenv;
   s_env_nalloc = new_n;
   }
 
   script_env[i] = newstring;
   script_env[i+1] = 0;
   }
 
		    *//*
		      * script_unsetenv - remove a variable from the environment
		      * for scripts.
		    */
#define script_unsetenv(var)
/*
   void
   script_unsetenv(var)
   char *var;
   {
   int vl = strlen(var);
   int i;
   char *p;
 
   if (script_env == 0)
   return;
   for (i = 0; (p = script_env[i]) != 0; ++i) {
   if (strncmp(p, var, vl) == 0 && p[vl] == '=') {
   free(p);
   while ((script_env[i] = script_env[i+1]) != 0)
   ++i;
   break;
   }
   }
   }
 */
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.