This is libmsql.c in view mode; [Download] [Up]
/* ** libmsql.c - ** ** ** Copyright (c) 1993-95 David J. Hughes ** Copyright (c) 1995 Hughes Technologies Pty Ltd ** ** Permission to use, copy, and distribute for non-commercial purposes, ** is hereby granted without fee, providing that the above copyright ** notice appear in all copies and that both the copyright notice and this ** permission notice appear in supporting documentation. ** ** This software is provided "as is" without any expressed or implied warranty. ** ** ID = "$Id:" ** */ #include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h> #include <netdb.h> #include <pwd.h> #include <stdlib.h> #include <varargs.h> #include <string.h> #include "common/portability.h" #ifdef HAVE_SYS_UN_H # include <sys/un.h> #endif #include "common/site.h" #include "msql_priv.h" #include "errmsg.h" #define _LIB_SOURCE #include "msql.h" #ifndef INADDR_NONE #define INADDR_NONE -1 #endif static char serverInfo[80], hostInfo[80]; static int curServerSock, numFields, queryTableSize, fieldTableSize, protoInfo; static m_data *tmpDataStore = NULL, *queryData = NULL, *fieldData = NULL; char msqlErrMsg[160]; RETSIGTYPE (*oldHandler)(); static void msqlDebug(); #define resetError() (void)bzero(msqlErrMsg,sizeof(msqlErrMsg)) #define chopError() { char *cp; cp = msqlErrMsg+strlen(msqlErrMsg) -1; \ if (*cp == '\n') *cp = 0;} extern char *packet; #define safeFree(x) {if(x) { (void)free(x); x = NULL; } } /************************************************************************** ** _ msqlInitDebug ** ** Purpose : ** Args : ** Returns : ** Notes : */ #define MOD_QUERY 1 #define MOD_API 2 #define MOD_MALLOC 4 #define MOD_ERROR 8 static int debugLevel=0, debugInit = 0; static void msqlInitDebug() { char *env, *tmp, *tok; env = getenv("MINERVA_DEBUG"); if(env) { tmp = (char *)strdup(env); } else return; printf("\n-------------------------------------------------------\n"); printf("MINERVA_DEBUG found. libmsql started with the following:-\n\n"); tok = (char *)strtok(tmp,":"); while(tok) { if (strcmp(tok,"msql_query") == 0) { debugLevel |= MOD_QUERY; printf("Debug level : query\n"); } if (strcmp(tok,"msql_api") == 0) { debugLevel |= MOD_API; printf("Debug level : api\n"); } if (strcmp(tok,"msql_malloc") == 0) { debugLevel |= MOD_MALLOC; printf("Debug level : malloc\n"); } tok = (char *)strtok(NULL,":"); } safeFree(tmp); printf("\n-------------------------------------------------------\n\n"); } /************************************************************************** ** _msqlDebug ** ** Purpose : ** Args : ** Returns : ** Notes : */ static void msqlDebug(va_alist) va_dcl { va_list args; char msg[1024], *fmt; int module, out = 0; va_start(args); module = (int) va_arg(args, int *); if (! (module & debugLevel)) { va_end(args); return; } fmt = (char *)va_arg(args, char *); if (!fmt) return; (void)vsprintf(msg,fmt,args); va_end(args); printf("[libmsql] %s",msg); fflush(stdout); } /************************************************************************** ** _setServerSock ** ** Purpose : Store the server socket currently in use ** Args : Server socket ** Returns : Nothing ** Notes : The current socket is stored so that the signal ** handlers know which one to shut down. */ static void setServerSock(sock) int sock; { curServerSock = sock; } /************************************************************************** ** _closeServer ** ** Purpose : Shut down the server connection ** Args : Server socket ** Returns : Nothing ** Notes : This is used by msqlClose and the signal handlers */ static void closeServer(sock) int sock; { msqlDebug(MOD_API,"Server socket (%d) closed\n", sock); shutdown(sock,2); close(sock); } /************************************************************************** ** _msqlClose ** ** Purpose : Send a QUIT to the server and close the connection ** Args : Server socket ** Returns : Nothing ** Notes : */ void msqlClose(sock) int sock; { char buf[6]; setServerSock(sock); sprintf(packet,"%d:\n",QUIT); writePkt(sock); closeServer(sock); } /************************************************************************** ** _pipeHandler ** ** Purpose : Close the server connection if we get a SIGPIPE ** Args : sig ** Returns : Nothing ** Notes : */ RETSIGTYPE pipeHandler(sig) int sig; { msqlDebug(MOD_API,"Hit by pipe signal\n"); closeServer(curServerSock); signal(SIGPIPE,pipeHandler); return; } static freeQueryData(cur) m_data *cur; { m_data *prev; int offset; while(cur) { offset = 0; while(offset < cur->width) { safeFree(cur->data[offset]); offset++; } safeFree(cur->data); prev = cur; cur = cur->next; safeFree(prev); msqlDebug(MOD_MALLOC, "Query data row - free @ %X\n", prev); } safeFree(cur); } static freeFieldList(fieldData) m_fdata *fieldData; { m_fdata *cur, *prev; cur = fieldData; while(cur) { prev = cur; cur = cur->next; safeFree(prev->field.table); safeFree(prev->field.name); safeFree(prev); msqlDebug(MOD_MALLOC, "Field List Entry- free @ %X\n", prev); } } /************************************************************************** ** _msqlFreeResult ** ** Purpose : Free the memory allocated to a table returned by a select ** Args : Pointer to head of table ** Returns : Nothing ** Notes : */ void msqlFreeResult(result) m_result *result; { freeQueryData(result->queryData); freeFieldList(result->fieldData); safeFree(result); msqlDebug(MOD_MALLOC,"Result Handle - Free @ %X\n",result); } static m_fdata *tableToFieldList(data) m_data *data; { m_data *curRow; m_fdata *curField, *prevField, *head = NULL; curRow = data; while(curRow) { curField = (m_fdata *)malloc(sizeof(m_fdata)); msqlDebug(MOD_MALLOC,"Field List Entry - malloc @ %X of %d\n", curField, sizeof(m_fdata)); (void)bzero(curField, sizeof(m_fdata)); if (head) { prevField->next = curField; prevField = curField; } else { head = prevField = curField; } curField->field.table = (char *)strdup((char *)curRow->data[0]); curField->field.name = (char *)strdup((char *)curRow->data[1]); curField->field.type = atoi((char*)curRow->data[2]); curField->field.length = atoi((char*)curRow->data[3]); curField->field.flags = 0; if (*curRow->data[4] == 'Y') curField->field.flags |= NOT_NULL_FLAG; if (*curRow->data[5] == 'Y') curField->field.flags |= PRI_KEY_FLAG; curRow = curRow->next; } return(head); } /************************************************************************** ** _msqlConnect ** ** Purpose : Form a connection to a mSQL server ** Args : hostname of server ** Returns : socket for further use. -1 on error ** Notes : If host == NULL, localhost is used via UNIX domain socket */ int msqlConnect(host) char *host; { char *cp, *envVar, *unixPort; struct sockaddr_in IPaddr; #ifdef HAVE_SYS_UN_H struct sockaddr_un UNIXaddr; #endif struct servent *serv_ptr; struct hostent *hp; u_long IPAddr; int opt, version, sock, tcpPort; struct passwd *pw; resetError(); initNet(); if (!debugInit) { debugInit++; msqlInitDebug(); } /* ** Grab a socket and connect it to the server */ #ifndef HAVE_SYS_UN_H if (!host) { host = "localhost"; } #endif if (!host) { #ifdef HAVE_SYS_UN_H /* Shouldn't get in here with UNIX socks */ unixPort = MSQL_UNIX_ADDR; if ((envVar = getenv("MSQL_UNIX_PORT"))) { unixPort = envVar; } strcpy(hostInfo,"Localhost via UNIX socket"); msqlDebug(MOD_API,"Server name = NULL. Using UNIX sock(%s)\n", unixPort); sock = socket(AF_UNIX,SOCK_STREAM,0); if (sock < 0) { sprintf(msqlErrMsg,SOCKET_ERROR); return(-1); } setServerSock(sock); opt = 1; setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, sizeof(opt)); (void)bzero(&UNIXaddr,sizeof(UNIXaddr)); UNIXaddr.sun_family = AF_UNIX; strcpy(UNIXaddr.sun_path, unixPort); if(connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr))<0) { sprintf(msqlErrMsg,CONNECTION_ERROR); close(sock); return(-1); } #endif } else { tcpPort = MSQL_PORT; if ((serv_ptr = getservbyname("msql", "tcp"))) { tcpPort = serv_ptr->s_port; } if ((envVar = getenv("MSQL_TCP_PORT"))) { tcpPort = atoi(envVar); } sprintf(hostInfo,"%s via TCP/IP",host); msqlDebug(MOD_API,"Server name = %s. Using TCP sock (%d)\n", host, tcpPort); sock = socket(AF_INET,SOCK_STREAM,0); if (sock < 0) { sprintf(msqlErrMsg,IPSOCK_ERROR); return(-1); } setServerSock(sock); opt = 1; setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt, sizeof(opt)); (void)bzero(&IPaddr,sizeof(IPaddr)); IPaddr.sin_family = AF_INET; /* ** The server name may be a host name or IP address */ if ((IPAddr = inet_addr(host)) != INADDR_NONE) { bcopy(&IPAddr,&IPaddr.sin_addr,sizeof(IPAddr)); } else { hp = gethostbyname(host); if (!hp) { sprintf(msqlErrMsg, UNKNOWN_HOST, host); close(sock); return(-1); } bcopy(hp->h_addr,&IPaddr.sin_addr, hp->h_length); } IPaddr.sin_port = htons(tcpPort); if(connect(sock,(struct sockaddr *) &IPaddr, sizeof(IPaddr))<0) { sprintf(msqlErrMsg,CONN_HOST_ERROR, host); perror("Connect"); close(sock); return(-1); } } oldHandler = signal(SIGPIPE,pipeHandler); msqlDebug(MOD_API,"Connection socket = %d\n",sock); /* ** Check the greeting message and save the version info */ if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result. First check the status code from the ** server and then the protocol version. If the status == -1 ** or the protocol doesn't match our version, bail out! */ if (atoi(packet) == -1) { if (cp = (char *)index(packet,':')) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } closeServer(sock); return(-1); } cp = (char *)index(packet,':'); if (!cp) { strcpy(msqlErrMsg,PACKET_ERROR); closeServer(sock); return(-1); } version = atoi(cp + 1); if (version != PROTOCOL_VERSION) { sprintf(msqlErrMsg, VERSION_ERROR, version, PROTOCOL_VERSION); closeServer(sock); return(-1); } msqlDebug(MOD_API,"mSQL protocol version - API=%d, server=%d\n", PROTOCOL_VERSION, version); protoInfo = version; cp = (char *)index(cp+1,':'); if (cp) { msqlDebug(MOD_API,"Server greeting = '%s'\n",cp+1); strcpy(serverInfo,cp+1); } else { strcpy(serverInfo,"Error in server handshake!"); } if (*(serverInfo+strlen(cp+1)-1) == '\n') { *(serverInfo+strlen(cp+1)-1) = 0; } /* ** Send the username for this process for ACL checks */ pw = getpwuid(getuid()); if (!pw) { strcpy(msqlErrMsg,USERNAME_ERROR); closeServer(sock); return(-1); } (void)sprintf(packet,"%s\n",pw->pw_name); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result */ if (atoi(packet) == -1) { char *cp; cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } closeServer(sock); return(-1); } return(sock); } /************************************************************************** ** _msqlInitDB ** ** Purpose : Tell the server which database we want to use ** Args : Server sock and DB name ** Returns : -1 on error ** Notes : */ int msqlSelectDB(sock,db) int sock; char *db; { int res; msqlDebug(MOD_API,"Select Database = \"%s\"\n",db); resetError(); setServerSock(sock); /* ** Issue the init DB command */ (void)sprintf(packet,"%d:%s\n",INIT_DB,db); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result */ if (atoi(packet) == -1) { char *cp; cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } return(0); } /************************************************************************** ** _msqlStoreResult ** ** Purpose : Store the data returned from a query ** Args : None ** Returns : Result handle or NULL if no data ** Notes : */ m_result *msqlStoreResult() { m_result *tmp; if (!queryData && !fieldData) { return(NULL); } tmp = (m_result *)malloc(sizeof(m_result)); msqlDebug(MOD_MALLOC,"Result Handle - malloc @ %X of %d\n", tmp, sizeof(m_result)); if (!tmp) { return(NULL); } (void)bzero(tmp, sizeof(m_result)); tmp->queryData = queryData; tmp->numRows = queryTableSize; tmp->fieldData = tableToFieldList(fieldData); tmp->numFields = fieldTableSize; tmp->cursor = tmp->queryData; tmp->fieldCursor = tmp->fieldData; freeQueryData(fieldData); queryData = NULL; fieldData = NULL; return(tmp); } /************************************************************************** ** _msqlFetchField ** ** Purpose : Return a row of the query results ** Args : result handle ** Returns : pointer to row data ** Notes : */ m_field *msqlFetchField(handle) m_result *handle; { m_field *tmp; if (!handle->fieldCursor) { return(NULL); } tmp = &(handle->fieldCursor->field); handle->fieldCursor = handle->fieldCursor->next; return(tmp); } /************************************************************************** ** _msqlFetchRow ** ** Purpose : Return a row of the query results ** Args : result handle ** Returns : pointer to row data ** Notes : */ m_row msqlFetchRow(handle) m_result *handle; { m_row tmp; if (!handle->cursor) { return(NULL); } tmp = handle->cursor->data; handle->cursor = handle->cursor->next; return(tmp); } /************************************************************************** ** _msqlFieldSeek ** ** Purpose : Move the result cursor ** Args : result handle, offset ** Returns : Nothing. Just sets the cursor ** Notes : The data is a single linked list so we can go backwards */ void msqlFieldSeek(handle, offset) m_result *handle; int offset; { m_fdata *tmp; msqlDebug(MOD_API,"msqlFieldSeek() pos = \n",offset); tmp = handle->fieldData; while(offset) { if (!tmp) break; tmp = tmp->next; offset--; } handle->fieldCursor = tmp; } /************************************************************************** ** _msqlDataSeek ** ** Purpose : Move the result cursor ** Args : result handle, offset ** Returns : Nothing. Just sets the cursor ** Notes : The data is a single linked list so we can go backwards */ void msqlDataSeek(handle, offset) m_result *handle; int offset; { m_data *tmp; msqlDebug(MOD_API,"msqlDataSeek() pos = \n",offset); tmp = handle->queryData; while(offset) { if (!tmp) break; tmp = tmp->next; offset--; } handle->cursor = tmp; } /************************************************************************** ** _ ** ** Purpose : ** Args : ** Returns : ** Notes : */ int msqlQuery(sock,q) int sock; char *q; { int len, res; char *cp; msqlDebug(MOD_QUERY,"Query = \"%s\"\n",q); resetError(); setServerSock(sock); /* ** Issue the query */ (void)sprintf(packet,"%d:%s\n",QUERY,q); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result. It may be an indication of further data to ** come (ie. from a select) */ if (atoi(packet) == -1) { cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } cp = (char *)index(packet,':'); numFields = 0; if (cp) { numFields = atoi(cp+1); if (numFields <= 0) return(0); } else { return(0); } /* ** numFields > 0 therefore we have data waiting on the socket. ** Grab it and dump it into a table structure. If there's ** uncollected data free it - it's no longer available. */ if (queryData) { freeQueryData(queryData); freeQueryData(fieldData); queryData = NULL; fieldData = NULL; } queryTableSize = readQueryData(sock); if (queryTableSize < 0) { return(-1); } queryData = tmpDataStore; tmpDataStore = NULL; numFields = 6; fieldTableSize = readQueryData(sock); if (fieldTableSize < 0) { return(-1); } fieldData = tmpDataStore; tmpDataStore = NULL; return(0); } /************************************************************************** ** _ ** ** Purpose : ** Args : ** Returns : ** Notes : */ int readQueryData(sock) int sock; { int off, len, numRows; char *cp; m_data *cur; if (readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } numRows = 0; while(atoi(packet) != -100) { if (atoi(packet) == -1) { cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } numRows++; if(!tmpDataStore) { tmpDataStore = cur = (m_data *)malloc(sizeof(m_data)); } else { cur->next = (m_data *)malloc(sizeof(m_data)); cur = cur->next; } msqlDebug(MOD_MALLOC,"Query data row - malloc @ %X of %d\n", cur, sizeof(m_data)); (void)bzero(cur,sizeof(m_data)); cur->data = (char **)malloc(numFields * sizeof(char *)); (void)bzero(cur->data,numFields * sizeof(char *)); cur->width = numFields; off = 0; cp = packet; while(off < numFields) { len = atoi(cp); cp = (char *)index(cp,':'); if (len == -2) { cur->data[off] = (u_char *)NULL; cp++; } else { cur->data[off] = (u_char *)malloc(len+1); (void)bzero(cur->data[off],len+1); (void)bcopy(cp+1,cur->data[off],len); cp += len + 1; } off++; } if (readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } } return(numRows); } /************************************************************************** ** _ ** ** Purpose : ** Args : ** Returns : ** Notes : */ m_result *msqlListDBs(sock) int sock; { m_result *tmp; msqlDebug(MOD_API,"msqlListDBs(%d)\n",sock); tmp = (m_result *)malloc(sizeof(m_result)); if (!tmp) { return(NULL); } (void)bzero(tmp, sizeof(m_result)); msqlDebug(MOD_MALLOC,"Result Handle - malloc @ %X of %d\n", tmp, sizeof(m_result)); sprintf(packet,"%d:\n",DB_LIST); writePkt(sock); numFields = 1; tmp->numRows = readQueryData(sock); if (tmp->numRows < 0) { (void)free(tmp); return(NULL); } tmp->queryData = tmpDataStore; tmp->cursor = tmp->queryData; tmp->numFields = 1; tmp->fieldData = (m_fdata *)malloc(sizeof(m_fdata)); msqlDebug(MOD_MALLOC,"Field List Entry - malloc @ %X of %d\n", tmp->fieldData, sizeof(m_fdata)); (void)bzero(tmp->fieldData, sizeof(m_fdata)); tmp->fieldData->field.table = (char *)strdup("mSQL Catalog"); tmp->fieldData->field.name = (char *)strdup("Database"); tmp->fieldData->field.type = CHAR_TYPE; tmp->fieldData->field.length = NAME_LEN; tmp->fieldData->field.flags = 0; tmp->fieldCursor = tmp->fieldData; tmpDataStore = NULL; return(tmp); } /************************************************************************** ** _ ** ** Purpose : ** Args : ** Returns : ** Notes : */ m_result *msqlListTables(sock) int sock; { m_result *tmp; msqlDebug(MOD_API,"msqlListTables(%d)\n",sock); tmp = (m_result *)malloc(sizeof(m_result)); if (!tmp) { return(NULL); } msqlDebug(MOD_MALLOC,"Result Handle - malloc @ %X of %d\n", tmp, sizeof(m_result)); (void)bzero(tmp, sizeof(m_result)); sprintf(packet,"%d:\n",TABLE_LIST); writePkt(sock); numFields = 1; tmp->numRows = readQueryData(sock); if (tmp->numRows < 0) { (void)free(tmp); return(NULL); } tmp->queryData = tmpDataStore; tmp->numFields = 0; tmp->cursor = tmp->queryData; tmp->fieldCursor = NULL; tmpDataStore = NULL; tmp->numFields = 1; tmp->fieldData = (m_fdata *)malloc(sizeof(m_fdata)); msqlDebug(MOD_MALLOC,"Field List Entry - malloc @ %X of %d\n", tmp->fieldData, sizeof(m_fdata)); (void)bzero(tmp->fieldData, sizeof(m_fdata)); tmp->fieldData->field.table = (char *)strdup("mSQL Catalog"); tmp->fieldData->field.name = (char *)strdup("Table"); tmp->fieldData->field.type = CHAR_TYPE; tmp->fieldData->field.length = NAME_LEN; tmp->fieldData->field.flags = 0; tmp->fieldCursor = tmp->fieldData; return(tmp); } /************************************************************************** ** _ ** ** Purpose : ** Args : ** Returns : ** Notes : */ m_result *msqlListFields(sock,table) int sock; char *table; { m_result *tmp; msqlDebug(MOD_API,"msqlListFields(%d,%s)\n",sock,table); tmp = (m_result *)malloc(sizeof(m_result)); if (!tmp) { return(NULL); } msqlDebug(MOD_MALLOC,"Result Handle - malloc @ %X of %d\n", tmp, sizeof(m_result)); (void)bzero(tmp, sizeof(m_result)); sprintf(packet,"%d:%s\n",FIELD_LIST,table); writePkt(sock); numFields = 6; tmp->numFields = readQueryData(sock); if(tmp->numFields < 0) { (void)free(tmp); return(NULL); } tmp->fieldData = tableToFieldList(tmpDataStore); tmp->fieldCursor = tmp->fieldData; tmp->queryData = NULL; tmp->cursor = NULL; tmp->numRows = 0; freeQueryData(tmpDataStore); tmpDataStore = NULL; return(tmp); } int msqlCreateDB(sock,DB) int sock; char *DB; { char *cp; msqlDebug(MOD_API,"msqlCreateDB(%d,%s)\n",sock,DB); sprintf(packet,"%d:%s\n",CREATE_DB,DB); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result. */ if (atoi(packet) == -1) { cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } return(0); } int msqlDropDB(sock,DB) int sock; char *DB; { char *cp; msqlDebug(MOD_API,"msqlDropDB(%d,%s)\n",sock,DB); sprintf(packet,"%d:%s\n",DROP_DB,DB); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result. */ if (atoi(packet) == -1) { cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } return(0); } int msqlShutdown(sock) int sock; { char *cp; msqlDebug(MOD_API,"msqlShutdown(%d)\n",sock); sprintf(packet,"%d:\n",SHUTDOWN); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result. */ if (atoi(packet) == -1) { cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } return(0); } int msqlReloadAcls(sock) int sock; { char *cp; msqlDebug(MOD_API,"msqlReloadAcl(%d)\n",sock); sprintf(packet,"%d:\n",RELOAD_ACL); writePkt(sock); (void)bzero(packet,PKT_LEN); if(readPkt(sock) <= 0) { closeServer(sock); strcpy(msqlErrMsg,SERVER_GONE_ERROR); return(-1); } /* ** Check the result. */ if (atoi(packet) == -1) { cp = (char *)index(packet,':'); if (cp) { strcpy(msqlErrMsg,cp+1); chopError(); } else { strcpy(msqlErrMsg,UNKNOWN_ERROR); } return(-1); } return(0); } char *msqlGetServerInfo() { return(serverInfo); } char *msqlGetHostInfo() { return(hostInfo); } int msqlGetProtoInfo() { return(protoInfo); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.