/* NAME * do_unix.c * * DESCRIPTION * Executes a unix command with popen, returns the results as a set. * Note that the command is executed as user miadmin. * * BUILD INSTRUCTIONS * * OSF1: cc -I$MI_HOME/h -c do_unix.c * ld -shared -expect_unresolved '*' -o do_unix.so do_unix.o * * chmod a+x do_unix.so * * DATABASE CREATE * * create function do_unix (text) returns setof(text) * as external name '/FULLPATH/do_unix.so(do_unix)' language C; * * create type unix_t (unix_results text); * * create function unix (text) * returns setof(unix_t) * as select unix_results from do_unix($1) unix_results; * * SAMPLE USAGE * * % msql template1 -w0 * * * select * from unix ('uname -a'); * ---------------------------- * |unix_results | * ---------------------------- * |OSF1 mighty V1.3 111 alpha| * ---------------------------- * one row selected * * * select * from unix ('who'); * ----------------------------------------------------------------- * |unix_results | * ----------------------------------------------------------------- * |jta :0 Oct 06 08:14 | * |miadmin ttyp5 Oct 06 09:18 (mighty.sdsc.edu)| * ----------------------------------------------------------------- * 2 rows selected * * $Header: /usr/local/devel/montage/samples/functions/RCS/do_unix.c,v 1.1 1994/10/06 16:27:13 jta Exp $ */ #include "mi.h" #include #include typedef struct unixstate { MI_CONNECTION *conn; FILE *strm; } UnixState; mi_text * do_unix ARGS(( mi_text *command, MI_FPARAM *fParam)); mi_text * do_unix(str, fParam) mi_text *str; MI_FPARAM *fParam; { mi_text *retval; char *r = "do_unix", *command, msg_buf[100], result[256]; UnixState *unixState; FILE *popen(); switch(MI_FP_REQUEST(fParam)) { case SET_INIT: unixState = (UnixState *) mi_alloc(sizeof(UnixState)); MI_FP_SETFUNCSTATE(fParam, (void *) unixState); mi_set_mem_duration(unixState, PER_COMMAND); if(MI_FP_ARGISNULL(fParam, 0)) { MI_FP_SETRETURNISNULL(fParam, MI_TRUE); break; } if ((unixState->conn = mi_open(NULL, NULL, NULL)) == (MI_CONNECTION *)NULL) { sprintf(msg_buf, "%s: could not get illustra connection",r); mi_db_error_raise(unixState->conn, MI_EXCEPTION, msg_buf); } command = mi_text_to_string(str); /* execute the command.... */ if((unixState->strm = popen(command, "r")) == NULL) { sprintf(msg_buf, "popen failed"); mi_db_error_raise(unixState->conn, MI_MESSAGE, msg_buf); } break; case SET_RETONE: unixState = (UnixState *) MI_FP_FUNCSTATE(fParam); if(fgets(result, sizeof(result), unixState->strm) == NULL) { MI_FP_SETISDONE(fParam, MI_TRUE); break; } if(result[strlen(result)-1] == '\n') /* Get rid of newline */ result[strlen(result)-1] = '\0'; retval = mi_string_to_text(result); return(retval); case SET_END: unixState = (UnixState *) MI_FP_FUNCSTATE(fParam); pclose(unixState->strm); if (mi_close(unixState->conn) == MI_ERROR) { sprintf(msg_buf, "%s: could not close %s connection", r); mi_db_error_raise(unixState->conn, MI_MESSAGE, msg_buf); } mi_free(unixState); break; } }