summaryrefslogtreecommitdiffstats
path: root/funtools/util/mainlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'funtools/util/mainlib.c')
-rw-r--r--funtools/util/mainlib.c790
1 files changed, 0 insertions, 790 deletions
diff --git a/funtools/util/mainlib.c b/funtools/util/mainlib.c
deleted file mode 100644
index fd3da89..0000000
--- a/funtools/util/mainlib.c
+++ /dev/null
@@ -1,790 +0,0 @@
-/*
- * Copyright (c) 2004 Smithsonian Astrophysical Observatory
- */
-
-/*
- * mainlib.c -- support for main routines called as library subroutines
- *
- */
-
-#include <mainlib.h>
-
-extern char *optarg;
-extern int optind;
-
-/*
- *
- * private routines
- *
- */
-
-/*
- *----------------------------------------------------------------------------
- *
- * Routine: Pipe2Buf
- *
- * Purpose: read pipe til EOF and fill buffer with results
- *
- * Results: number of bytes read (and buffer in passed argument)
- *
- *----------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-static int
-Pipe2Buf(int fd, char **buf)
-#else
-static int Pipe2Buf(fd, buf)
- int fd;
- char **buf;
-#endif
-{
- int got;
- int clen=0;
- int blen=0;
-
- /* initial buffer size */
- blen = SZ_LINE*10;
- *buf = xmalloc(blen);
-
- /* read til EOF and fill buffer */
- while( 1 ){
- /* reallocate as needed */
- if( (clen + SZ_LINE) >= blen ){
- blen += SZ_LINE*10;
- *buf = xrealloc(*buf, blen);
- }
- /* read */
- got=read(fd, *buf+clen, SZ_LINE);
- /* got data */
- if( got > 0 ){
- clen += got;
- continue;
- }
- /* EOF */
- else if( got == 0 ){
- /* reallocate to actual size, but null terminate as a courtesy */
- blen = clen+1;
- *buf = xrealloc(*buf, blen);
- *(*buf+clen) = '\0';
- break;
- }
- /* error */
- else{
- xfree(*buf);
- blen = -1;
- break;
- }
- }
- /* return the news */
- return blen;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * Routine: MainLibListAdd
- *
- * Purpose: add a member of an mainlib list
- *
- * Results: 1 on success, 0 for failure
- *
- *---------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-static void
-MainLibListAdd (MainLib ml, MainLibEntry mle)
-#else
-static void MainLibListAdd(ml, mle)
- MainLib ml;
- MainLibEntry mle;
-#endif
-{
- MainLibEntry cur;
-
- if( ml->head == NULL ){
- ml->head = mle;
- }
- else{
- for(cur=ml->head; cur->next!=NULL; cur=cur->next)
- ;
- cur->next = mle;
- }
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * Routine: MainLibListDel
- *
- * Purpose: remove a member of an mainlib list
- *
- * Results: 1 on success, 0 for failure
- *
- *---------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-static void
-MainLibListDel (MainLib ml, MainLibEntry mle)
-#else
-static void MainLibListDel(ml, mle)
- MainLib ml;
- MainLibEntry mle;
-#endif
-{
- MainLibEntry cur;
-
- /* remove from list of mainlibs */
- if( ml->head ){
- if( ml->head == mle ){
- ml->head = mle->next;
- }
- else{
- for(cur=ml->head; cur!=NULL; cur=cur->next){
- if( cur->next == mle ){
- cur->next = mle->next;
- break;
- }
- }
- }
- }
-}
-
-/*
- *
- * semi-public routines
- *
- */
-
-/*
- *---------------------------------------------------------------------------
- *
- * Routine: MainLibLookup
- *
- * Purpose: lookup a mainlib procedure
- *
- * Results: MainLibEntry record on success, NULL on failure
- *
- *---------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-MainLibEntry
-MainLibLookup (MainLib ml, char *xclass, char *name)
-#else
-MainLibEntry MainLibLookup(ml, xclass, name)
- MainLib ml;
- char *xclass;
- char *name;
-#endif
-{
- MainLibEntry cur;
-
- if( !ml || (!xclass && !name) ) return NULL;
-
- for(cur=ml->head; cur!=NULL; cur=cur->next){
- if( (!xclass || !strcmp(xclass, cur->xclass)) &&
- (!name || !strcmp(name, cur->name)) ){
- return cur;
- }
- }
- return NULL;
-}
-
-/*
- *
- * public routines
- *
- */
-
-/*
- *----------------------------------------------------------------------------
- *
- * Routine: MainLibNew
- *
- * Purpose: create mainlib struct
- *
- * Returns: mainlib list handle or NULL
- *
- *----------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-MainLib
-MainLibNew (void)
-#else
-MainLib MainLibNew()
-#endif
-{
- MainLib ml;
-
- /* allocate struct */
- if( !(ml = (MainLib)xcalloc(1, sizeof(MainLibRec))) )
- return NULL;
- return ml;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * Routine: MainLibAdd
- *
- * Purpose: add a mainlib name to allow external processes to be called
- * as subroutines
- *
- * Returns: mainlib handle associated with this name or NULL
- *
- *----------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-MainLibEntry
-MainLibAdd (MainLib ml, char *xclass, char *name, MainLibProc proc, int type)
-#else
-MainLibEntry MainLibAdd(ml, xclass, name, proc, type)
- MainLib ml;
- char *xclass;
- char *name;
- MainLibProc proc;
- int type;
-#endif
-{
- MainLibEntry mle;
-
- /* sanity check */
- if( !ml ) return NULL;
-
- /* allocate struct */
- if( !(mle = (MainLibEntry)xcalloc(1, sizeof(MainLibEntryRec))) ) return NULL;
- /* fill in the blanks */
- mle->xclass = xstrdup(xclass);
- mle->name = xstrdup(name);
- mle->proc = proc;
- mle->type = type;
- /* add to list */
- MainLibListAdd(ml, mle);
- return mle;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * Routine: MainLibProcess
- *
- * Purpose: call external processes as subroutines
- *
- * Results: number of bytes in return buffer (buffer in passed argument)
- *
- *----------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-int MainLibProcess(MainLib ml, char *cmd, char **buf, char *mode)
-#else
-int MainLibProcess(ml, cmd, buf, mode)
- MainLib ml;
- char *cmd;
- char **buf;
- char *mode;
-#endif
-{
- int i, j;
- int got;
- int ncmd=0;
- int ip=0;
- int ifd=-1;
- int ofd=-1;
- int efd=-1;
- int fillbuf=1;
- int debug=0;
- int use_ifd=0;
- int use_ofd=0;
- int use_efd=0;
-#if HAVE_TCL
- int use_tcl=0;
-#endif
- int nargs[MAINLIB_CMDS+1];
- int pipes[MAINLIB_CMDS+1][2];
- char *c, *s, *t;
- char *undef=NULL;
- char tbuf[SZ_LINE];
- char ibuf[SZ_LINE];
- char ibuf2[SZ_LINE];
- char *args[(MAINLIB_CMDS+1)*MAINLIB_ARGS];
- char *cmds[MAINLIB_CMDS+1];
-#if HAVE_TCL
- void *tcl=NULL;
-#endif
- MainLibEntry mles[MAINLIB_CMDS+1];
- static int mainlibinit=0;
- static int mainlib_debug=0;
- static char *mainlib_path=NULL;
-
- /* sanity check */
- if( !ml ){
- gerror(stderr, "invalid or missing command list for mainlib\n");
- got = -1;
- goto done;
- }
-
- /* initialization */
- if( !mainlibinit ){
- if( (s = (char *)getenv("MAINLIB_DEBUG")) )
- mainlib_debug = istrue(s);
- mainlib_path = (char *)getenv("PATH");
- mainlibinit = 1;
- }
-
- /* clear arrays */
- memset(cmds, 0, sizeof(char *)*(MAINLIB_CMDS+1));
- memset(mles, 0, sizeof(MainLibEntry)*(MAINLIB_CMDS+1));
- memset(args, 0, sizeof(char *)*(MAINLIB_CMDS+1)*MAINLIB_ARGS);
-
- /* separate commands */
- c = xstrdup(cmd);
- for(s=c; (t=strchr(s, '|'))!=NULL; s=t+1){
- if( ncmd >= MAINLIB_CMDS ){
- gerror(stderr, "max cmds exceeded (%d) for mainlib\n", ncmd);
- got = -1;
- goto done;
- }
- *t = '\0';
- cmds[++ncmd] = xstrdup(s);
- }
- /* get last command */
- cmds[++ncmd] = xstrdup(s);
- if( c ) xfree(c);
-
- /* seed the debug flag (override with switch) */
- debug = mainlib_debug;
-
- /* check mode string */
- if( (t = xstrdup(mode)) ){
- if( keyword(t, "stdin", tbuf, SZ_LINE) ) ifd = atoi(tbuf);
- if( keyword(t, "stdout", tbuf, SZ_LINE) ) ofd = atoi(tbuf);
- if( keyword(t, "stderr", tbuf, SZ_LINE) ) efd = atoi(tbuf);
- if( keyword(t, "undef", tbuf, SZ_LINE) ) undef = xstrdup(tbuf);
- if( keyword(t, "fillbuf", tbuf, SZ_LINE) ) fillbuf = istrue(tbuf);
- if( keyword(t, "debug", tbuf, SZ_LINE) ) debug = istrue(tbuf);
-#if HAVE_TCL
- if( keyword(t, "tcl", tbuf, SZ_LINE) ){
- sscanf(tbuf, "%p", &tcl);
- use_tcl=1;
- }
-#endif
- xfree(t);
- }
- /* make sure unef is defined */
- if( !undef ){
- undef = xstrdup("extn");
- }
-
- /* pipe for top level */
- pipe(pipes[0]);
-
- /* package up arguments for each command */
- for(i=1; i<=ncmd; i++){
- if( pipe(pipes[i]) < 0 ){
- gerror(stderr, "can't set up pipes for mainlib\n");
- got = -1;
- goto done;
- }
- ip = 0;
- /* make sure we have a command */
- if( !word(cmds[i], ibuf, &ip) ){
- gerror(stderr, "invalid or missing command for mainlib\n");
- got = -1;
- goto done;
- }
- /* make sure its a valid command */
- nowhite(ibuf, ibuf2);
- if( !(mles[i] = MainLibLookup(ml, NULL, ibuf2)) ){
- if( undef ){
- ip = 0;
- while( word(undef, tbuf, &ip) ){
- if( !strcasecmp(tbuf, "error") ){
- break;
- }
-#if HAVE_TCL
- else if( use_tcl && ml->tcllookup && ml->tcllookup(tcl, ibuf2) ){
- mles[i] = MainLibAdd(ml, cmds[i], ibuf2, NULL, MAINLIB_TCL);
- break;
- }
-#endif
- else if( (s=Find(ibuf2, "x", NULL, mainlib_path)) != NULL ){
- mles[i] = MainLibAdd(ml, s, ibuf2, NULL, MAINLIB_EXTN);
- xfree(s);
- break;
- }
- }
- if( !mles[i] ){
- gerror(stderr, "can't locate procedure '%s' for mainlib\n", ibuf);
- got = -1;
- goto done;
- }
- }
-#ifdef OLD
- switch(mainlibundef){
- case MAINLIB_ERROR:
- gerror(stderr, "can't locate procedure '%s' for mainlib\n", ibuf);
- got = -1;
- goto done;
- case MAINLIB_EXTN:
- if( (s=Find(ibuf2, "x", NULL, mainlib_path)) != NULL ){
- mles[i] = MainLibAdd(ml, s, ibuf2, NULL, MAINLIB_EXTN);
- xfree(s);
- }
- else
- gerror(stderr, "can't locate procedure '%s' for mainlib\n", ibuf);
- break;
- default:
- gerror(stderr, "can't locate procedure '%s' for mainlib\n", ibuf);
- got = -1;
- goto done;
- }
-#endif
-
- }
-
- /* package up the arguments */
- ip = 0;
- nargs[i] = 0;
- while( word(cmds[i], ibuf, &ip) ){
- nowhite(ibuf, ibuf2);
- if( *ibuf2 ){
- if( nargs[i] >= (MAINLIB_ARGS-1) ){
- gerror(stderr, "max args exceeded (%d) for mainlib\n", nargs[i]);
- got = -1;
- goto done;
- }
- args[i*MAINLIB_ARGS+nargs[i]] = xstrdup(ibuf2);
- nargs[i]++;
- args[i*MAINLIB_ARGS+nargs[i]] = NULL;
- }
- }
- }
-
- /* execute all commands */
- for(i=1; i<=ncmd; i++){
- /* fork new process */
- if( (ml->pids[i] = fork()) == -1 ){
- gerror(stderr, "can't fork()\n");
- got = -1;
- goto done;
- }
- /* child will call mainlib routine */
- if( ml->pids[i] == 0 ){
- /* reset optind in case its being used by child */
- optind = 1;
- /* stdin for this new process is */
- if( i == 1 ){
- /* first process either reads stdin from specified ifd,
- or else we leave it alone */
- if( ifd >= 0 ){
- if( ifd != 0 ){
- close(0); dup(ifd);
- }
- else{
- use_ifd = 1;
- }
- }
- }
- /* all other processes read stdin from previous process stdout */
- else{
- close(0); dup(pipes[i][0]);
- }
- /* set up stdout for this new process */
- if( i < ncmd ){
- close(1); dup(pipes[i+1][1]);
- }
- else{
- /* last process either writes stdout or to specified ofd */
- if( ofd >= 0 ){
- if( ofd != 1 ){
- close(1); dup(ofd);
- }
- else{
- use_ofd = 1;
- }
- }
- /* or sends stdout to main process */
- else{
- close(1); dup(pipes[0][1]);
- }
- }
- /* all processes redirect stderr, if required */
- if( efd >= 0 ){
- if( efd != 2 ){
- close(2); dup(efd);
- }
- else{
- use_efd = 1;
- }
- }
- /* close all pipes */
- for(j=0; j<=ncmd; j++){
- close(pipes[j][0]); close(pipes[j][1]);
- }
- /* including user-specified pipes */
- if( (ifd >=0) && !use_ifd ) close(ifd);
- if( (ofd >=0) && !use_ofd ) close(ofd);
- if( (efd >=0) && !use_efd ) close(efd);
- /* call specified subroutine */
- switch(mles[i]->type){
- case MAINLIB_ARGV:
- if( debug )
- fprintf(stderr, "Executing MainLib: %s\n", args[i*MAINLIB_ARGS]);
- mles[i]->proc(nargs[i], &args[i*MAINLIB_ARGS]);
- break;
- case MAINLIB_EXTN:
- if( debug )
- fprintf(stderr, "Executing external program: %s\n", mles[i]->xclass);
- if( mles[i]->xclass )
- execvp(mles[i]->xclass, (void *)&args[i*MAINLIB_ARGS]);
- else
- execvp(mles[i]->name, (void *)&args[i*MAINLIB_ARGS]);
- break;
-#if HAVE_TCL
- case MAINLIB_TCL:
- if( debug )
- fprintf(stderr, "Executing Tcl proc: %s\n", mles[i]->xclass);
- if( use_tcl && ml->tcleval){
- ml->tcleval(tcl, mles[i]->xclass);
- }
- else{
- gerror(stderr, "Tcl support missing for mainlib\n");
- }
- break;
-#endif
- default:
- gerror(stderr, "unknown program type for mainlib\n");
- break;
- }
- _exit(0);
- }
- }
-
- /* close all pipes except the final input pipe */
- close(pipes[0][1]);
- for(i=1; i<=ncmd; i++){
- close(pipes[i][0]);
- close(pipes[i][1]);
- }
-
- /* if not filling buffer, just return the pipe (user calls cleanup) */
- if( !fillbuf ){
- got = pipes[0][0];
- ml->npid = ncmd;
- goto done2;
- }
-
- /* wait for output from last process */
- got = Pipe2Buf(pipes[0][0], buf);
-
- /* and now close final input pipe */
- close(pipes[0][0]);
-
-done:
- /* done with processing, wait for children to finish */
- MainLibProcessCleanup(ml);
-
-done2:
- /* free up space */
- for(i=1; i<=ncmd; i++){
- for(j=0; j<nargs[i]; j++){
- if( args[i*MAINLIB_ARGS+j] ) xfree(args[i*MAINLIB_ARGS+j]);
- }
- if( cmds[i] ) xfree(cmds[i]);
- }
- if( undef ) xfree(undef);
-
- /* return: error (-1), number of bytes in buffer, or pipe fd */
- return got;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * Routine: MainLibProcessCleanup
- *
- * Purpose: cleanup after mainlib processing
- *
- * Results: 1 on success, 0 for failure
- *
- *---------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-int
-MainLibProcessCleanup (MainLib ml)
-#else
-int MainLibProcessCleanup(ml)
- MainLib ml;
-#endif
-{
- int i;
- int status;
-
- for(i=1; i<=ml->npid; i++){
- if( ml->pids[i] ){
-#if HAVE_MINGW32==0
- while( waitpid(ml->pids[i], &status, 0) < 0 ){
- if( errno != EINTR ) break;
- }
-#endif
- ml->pids[i] = 0;
- }
- }
- return 1;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * Routine: MainLibDel
- *
- * Purpose: delete a MainLibEntry record structure
- *
- * Results: 0 on success, -1 for failure
- *
- *---------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-int
-MainLibDel (MainLib ml, MainLibEntry mle)
-#else
-int MainLibDel(ml, mle)
- MainLib ml;
- MainLibEntry mle;
-#endif
-{
-
- /* make sure we have something to do */
- if( !ml || !mle ) return -1;
-
- /* free up space */
- if( mle->xclass ) xfree(mle->xclass);
- if( mle->name ) xfree(mle->name);
-
- /* remove from list of mainlibs */
- MainLibListDel(ml, mle);
-
- /* free up record struct */
- xfree((char *)mle);
-
- return 0;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * Routine: MainLibFree
- *
- * Purpose: free all members of this mainlib list
- *
- * Results: 1 on success, 0 for failure
- *
- *---------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-int
-MainLibFree (MainLib ml)
-#else
-int MainLibFree(ml)
- MainLib ml;
-#endif
-{
- MainLibEntry mle, tmle;
-
- /* sanity check */
- if( !ml ) return 0;
-
- /* free all commands */
- for(mle=ml->head; mle!=NULL; ){
- tmle = mle->next;
- MainLibDel(ml, mle);
- mle = tmle;
- }
-
-#if HAVE_DLFCN_H
- /* release dynamic library */
- if( ml->dl ) dlclose(ml->dl);
-#endif
-
- /* free global struct */
- xfree(ml);
- return 1;
-}
-
-/*
- *----------------------------------------------------------------------------
- *
- * Routine: MainLibLoad
- *
- * Purpose: load shared library and execute init function
- *
- * Results: 0=>OK, -1=> no shared obj, -2=>no init function
- *
- *----------------------------------------------------------------------------
- */
-#ifdef ANSI_FUNC
-int MainLibLoad(char *name, char *shlib, void **ml, char **ermsg)
-#else
-int MainLibLoad(name, shlib, ml, ermsg)
- char *name;
- char *shlib;
- void **ml;
- char **ermsg;
-#endif
-{
-#if HAVE_DLFCN_H
- char tbuf[SZ_LINE];
- MainLibInitCall irtn=NULL;
- MainLib tml=NULL;
- void *tdl=NULL;
-
- /* sanity checks */
- if( !name ){
- if( ermsg ) *ermsg = "no package name specified";
- return -3;
- }
- if( !ml ){
- if( ermsg ) *ermsg = "no return ml struct specified";
- return -3;
- }
-
- /* get name of init call */
- snprintf(tbuf, SZ_LINE-1, "%sMainLibInit", name);
-
- /* load shared library */
- if( !(tdl=dlopen(shlib, RTLD_LAZY)) ){
- if( ermsg ) *ermsg = (char *)dlerror();
- return -1;
- }
-
- /* look up init funtion */
- if( !(irtn=(MainLibInitCall)dlsym(tdl, tbuf)) ){
- if( ermsg ) *ermsg = (char *)dlerror();
- return -2;
- }
-
- /* execute init function */
- tml = (*irtn)();
-
- /* store values */
- tml->dl = tdl;
-
- /* look up and return MainLibProcess funtion, if it exists */
- tml->mainlibprocess=(MainLibProcessCall)dlsym(tml->dl, "MainLibProcess");
-
- /* store MainLib record */
- *ml = tml;
-
- /* if we got here, its OK */
- return 0;
-#else
- /* avoid -W unused parameter warning */
- if( 0 ){
- name = name;
- shlib = shlib;
- ml = ml;
- }
- /* didn't find dlfcn.h */
- if( ermsg ) *ermsg = "dynamic load supported not found";
- return -1;
-#endif
-}