#if defined(AC_HAVE_SOCKET_JEAN) || defined(AC_HAVE_SOCKET) #ifdef AC_HAVE_SOCKET_JEAN #include "wac/acclient_socket_lib.c" #endif struct socket_descriptor { AceConnection aceconn_connection ; }; static void ac_partial_command_socket(AC_DB db, char *command, unsigned char **response, int *response_length, unsigned char **response_free, int *encore) { AceConnStatus status; struct socket_descriptor *d; d = db->db_access; status = AceConnRequest( d->aceconn_connection, command, (void *)response, response_length ); *response_free = *response; *encore = 0; } /* * the socket server transport does not have lazy commands, so we fake it. */ static void ac_lazy_command_socket( AC_DB db, char *command ) { int len, encore; unsigned char *response, *r_free; ac_partial_command_socket(db, command, &response, &len, &r_free, &encore); free(r_free); } void ac_close_socket(AC_DB db) { struct socket_descriptor *d; d = db->db_access; AceConnDisconnect(d->aceconn_connection); AceConnDestroy(d->aceconn_connection); messfree(d); } static char *ac_open_socket(AC_DB db, char *protocol, char *host, int port, char *other ) { struct socket_descriptor *d; char *user, *password; AceConnStatus status ; AceConnection connection = NULL ; int timeout = 0; while (! isdigit((int)*protocol) ) protocol++; if (*protocol == '/') protocol++; timeout = atoi(protocol); if ( timeout != 0 ) timeout = 300; d = halloc(sizeof(struct socket_descriptor), 0); /* * the database specifier is "acetcp:host:port" or "a:host:port" * but thanks to HTTP, people want to write "acetcp://host:port". * I will let them. */ while (*host == '/') host++; /* * a blank host name means the local host */ if (*host == '\0') host = "localhost"; /* * pluck the user/password out of the extra info from the database name */ user = NULL; if (! other || !other[0] ) { /* * the user field was missing or blank; try to get a username/password * from a config file. * * The environment variable ACEDB_USERNAME can either be a username/password * directly, or if it starts with a '/' it is a file that contains a list * of usernames & passwords for various servers. */ char *fname; fname = getenv("ACEDB_USERNAME"); if (fname) { if ( *fname != '/' ) user = strnew(fname, 0); else { FILE *f; f = fopen(fname,"r"); if (f) { char b[100], f_host[100], f_user[100], f_port[100]; while (fgets(b,sizeof(b),f)) { int n; char *s; if (b[0] == '/') continue; s = strchr(b,'\n'); if (s) *s = 0; n = sscanf(b,"%s%s%s",f_host, f_port, f_user); if (n != 3) continue; if ((f_host[0] != '*') && (strcmp(host, f_host) != 0)) continue; if ((f_port[0] != '*') && (port != atoi(f_port))) continue; user = strnew(f_user, 0); break; } fclose(f); } } } } else user = strnew(other,0); if (!user || !user[0]) return "must give user/password"; password = strchr(user, '/'); if (password) *password++ = 0; else password = ""; /* * it takes two calls to create the connection? */ status = AceConnCreate(&connection, host, port, user, password, timeout); if (status != ACECONN_OK) goto bad; status = AceConnConnect(connection) ; if (status != ACECONN_OK) goto bad; d->aceconn_connection = connection; db->ac_partial_command = ac_partial_command_socket; db->close_transport = ac_close_socket; db->lazy_command = ac_lazy_command_socket; db->db_access = d; messfree(user); return NULL; bad: if (user) messfree(user); if (connection) { char *error; error = connection->last_errmsg; /* free connection */ return error; } return "cannot contact server"; } #else static char *ac_open_socket(AC_DB db, char *protocol, char *host, int port, char *extras ) { return "000 Socket Server not supported in this library"; } #endif