diff options
Diffstat (limited to 'port.c')
-rw-r--r-- | port.c | 345 |
1 files changed, 345 insertions, 0 deletions
@@ -0,0 +1,345 @@ +/* + * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory + */ + +/* + * + * port.c -- xpa port management + * + */ + +#include <xpap.h> + +/* + *---------------------------------------------------------------------------- + * + * + * Private Routines + * + * + *---------------------------------------------------------------------------- + */ + +/* this is the head of the global list -- too lazy to do anything more */ +static PORT porthead=NULL; + +#ifdef ANSI_FUNC +static PORT +XPAPortLookup (char *xclass, char *name) +#else +static PORT XPAPortLookup(xclass, name) + char *xclass; + char *name; +#endif +{ + PORT cur; + /* look for exact match */ + for(cur=porthead; cur!=NULL; cur=cur->next){ + if( !strcmp(xclass, cur->xclass) && + !strcmp(name, cur->name) ){ + return(cur); + } + } + /* otherwise look for a template match */ + for(cur=porthead; cur!=NULL; cur=cur->next){ + if( tmatch(xclass, cur->xclass) && + tmatch(name, cur->name) ){ + return(cur); + } + } + return(NULL); +} + +/* + *---------------------------------------------------------------------------- + * + * Routine: XPAPortParse + * + * Purpose: parse port list into components + * + * Returns: 0 on success, -1 on failure + * + *---------------------------------------------------------------------------- + */ +#ifdef ANSI_FUNC +static int +XPAPortParse (char *lbuf, char *xclass, char *name, int *port, int len) +#else +static int XPAPortParse(lbuf, xclass, name, port, len) + char *lbuf; + char *xclass; + char *name; + int *port; + int len; +#endif +{ + char tbuf[SZ_LINE]; + int lp=0; + + /* init port values */ + *port = 0; + + /* class:name is required */ + if( word(lbuf, tbuf, &lp) ){ + XPAParseName(tbuf, xclass, name, len); + } + else{ + return(-1); + } + + /* port is required but can be "*" for default port */ + if( word(lbuf, tbuf, &lp) ){ + if( !strcmp(tbuf, "*") ) + *port = XPA_DEFPORT; + else + *port = atoi(tbuf); + } + else{ + return(-1); + } + + /* made it */ + return(0); +} + +/*---------------------------------------------------------------------------- + * + * + * Public Routines + * + * + *---------------------------------------------------------------------------- + */ + +/* + *---------------------------------------------------------------------------- + * + * Routine: XPAPortAdd + * + * Purpose: add one port entry to the xpa port list + * + * Returns: 0 on success, -1 on failure + * + *---------------------------------------------------------------------------- + */ +#ifdef ANSI_FUNC +int +XPAPortAdd (char *lbuf) +#else +int XPAPortAdd(lbuf) + char *lbuf; +#endif +{ + PORT xnew; + PORT cur; + char xclass[SZ_LINE]; + char name[SZ_LINE]; + int port; + + /* allocate port struct */ + if( (xnew = (PORT)xcalloc(1, sizeof(struct portrec))) == NULL ) + goto error; + + /* parse info from line buffer */ + if( XPAPortParse(lbuf, xclass, name, &port, SZ_LINE) < 0 ) + goto error; + + /* fill in the blanks */ + xnew->xclass = xstrdup(xclass); + xnew->name = xstrdup(name); + xnew->port = port; + + /* add this port to end of list of port's */ + if( porthead == NULL ){ + porthead = xnew; + } + else{ + for(cur=porthead; cur->next!=NULL; cur=cur->next) + ; + cur->next = xnew; + } + return(0); + +error: + if( xnew ) + xfree(xnew); + return(-1); +} + +/* + *--------------------------------------------------------------------------- + * + * Routine: XPAPortDel + * + * Purpose: free up alloc'ed memory in the port record structure + * + * Results: 0 on success, -1 for failure + * + *--------------------------------------------------------------------------- + */ +#ifdef ANSI_FUNC +int +XPAPortDel (PORT port) +#else +int XPAPortDel(port) + PORT port; +#endif +{ + PORT cur; + + if( port == NULL ) + return(-1); + + /* remove from list of port's */ + if( porthead ){ + if( porthead == port ){ + porthead = porthead->next; + } + else{ + for(cur=porthead; cur!=NULL; cur=cur->next){ + if( cur->next == port ){ + cur->next = (cur->next)->next; + break; + } + } + } + } + + /* free up string space */ + if( port->xclass ) xfree(port->xclass); + if( port->name ) xfree(port->name); + + /* free up record struct */ + xfree((char *)port); + return(0); +} + +/* + *---------------------------------------------------------------------------- + * + * Routine: XPAPortFree + * + * Purpose: + * + * Results: 1 on success, 0 for failure + * + *---------------------------------------------------------------------------- + */ +#ifdef ANSI_FUNC +void +XPAPortFree (void) +#else +void XPAPortFree() +#endif +{ + PORT cur; + PORT saveport; + + for(cur=porthead; cur!=NULL; ){ + saveport = cur->next; + XPAPortDel(cur); + cur = saveport; + } +} + +/* + *---------------------------------------------------------------------------- + * + * Routine: XPAPortNew + * + * Purpose: read or re-read the port list + * + * Results: number of lines in list (including default) + * + *---------------------------------------------------------------------------- + */ +#ifdef ANSI_FUNC +int +XPAPortNew (char *aname, int flag) +#else +int XPAPortNew(aname, flag) + char *aname; + int flag; +#endif +{ + int got=0; + char lbuf[SZ_LINE]; + char *s; + char *portname=NULL; + char *portpath=NULL; + char *portstr=NULL; + char *portcopy=NULL; + FILE *fp; + + /* if there is an old list, free it */ + if( flag == 0 ) + XPAPortFree(); + + /* get port file name */ + if( aname && *aname ) + portname = aname; + else if( (portname=(char *)getenv("XPA_PORTFILE")) == NULL ) + portname = XPA_PORTFILE; + + /* get the default port */ + portstr=(char *)getenv("XPA_PORT"); + + /* add the port assignments from environment first */ + if( portstr && *portstr ){ + portcopy=(char *)xstrdup(portstr); + for(s=(char *)strtok(portcopy,";"); s!=NULL; s=(char *)strtok(NULL,";")){ + if( XPAPortAdd(s) == 0 ) + got++; + } + if( portcopy) xfree(portcopy); + } + + /* add the port assignments from file next */ + if( (portpath=(char *)Access(portname, "r")) != NULL ){ + if( (fp=fopen(portpath, "r")) != NULL ){ + while( fgets(lbuf, SZ_LINE, fp) ){ + if( *lbuf == '#' ){ + continue; + } + if( XPAPortAdd(lbuf) == 0 ) + got++; + } + fclose(fp); + } + xfree(portpath); + } + + /* return the news */ + return(got); +} + +/* + *---------------------------------------------------------------------------- + * + * Routine: XPAPort + * + * Purpose: check for pre-defined port for a given class, name and + * 1 for com port, 2 for data port + * + * Results: assigned port or 0 + * + *---------------------------------------------------------------------------- + */ +#ifdef ANSI_FUNC +int +XPAPort (XPA xpa) +#else +int XPAPort(xpa) + XPA xpa; +#endif +{ + int p=0; + PORT cur; + + if( xpa == NULL ) + return 0; + if( (cur = XPAPortLookup(xpa->xclass, xpa->name)) ){ + p = cur->port; + } + return p; +} |