diff options
Diffstat (limited to 'g10/ks-proto.c')
-rw-r--r-- | g10/ks-proto.c | 299 |
1 files changed, 84 insertions, 215 deletions
diff --git a/g10/ks-proto.c b/g10/ks-proto.c index b862357fb..b5109f2ad 100644 --- a/g10/ks-proto.c +++ b/g10/ks-proto.c @@ -42,245 +42,114 @@ * X-Key-MTime: <last modification time> * X-Key-LID: <local_key_id_used_for_update_etc> * [fixme: is X-.... allowed?] + * */ #include <config.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <errno.h> +#include <ctype.h> #include "util.h" #include "ks-proto.h" -#if 0 -/**************** - * Read a protocol line - */ -static int -read_line( FILE *fp ) -{ - return -1; -} - - - - -/**************** - * Send a HKP request - */ -int -hkp_request( int operation, const char *user_id ) -{ - -} - - - - - -/************************************************ - ******* client communication stuff ************ - ************************************************/ - -/**************** - * Initialisieren des clients - * Es wird ein Handle zurückgegeben oder -1 bei einem fehler. - * z.Z. ist nut eine Verbindung gleichzeitig möglich. - * Wenn einer serverpid von 0 angegeben wird, so wird diese - * der environment variabeln ATEXDB_PID entnommen. - */ - -int -hkp_open( const char *serverurl ) -{ - const char *s; - - s = SERVER_NAME_TEMPLATE; - client.serv_name = xmalloc(strlen(s) + 10 ); - sprintf(client.serv_name,s, serverpid ); - if( opt.verbose ) - Info("Using unix domain stream '%s'", client.serv_name ); - - memset( &client.serv_addr, 0, sizeof client.serv_addr ); - client.serv_addr.sun_family = AF_UNIX; - strcpy( client.serv_addr.sun_path, client.serv_name ); - client.serv_addr_len = strlen(client.serv_addr.sun_path) - + sizeof client.serv_addr.sun_family; - - client.sockfd = -1; - if( DoCheckVersion() ) - return -1; - return 0; -} - - -static int -DoConnect() -{ - if( client.sockfd != -1 ) - DoDisconnect(); - if( (client.sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 ) { - Error(1000,"can't open unix domain socket"); - return 1; - } - if( connect(client.sockfd, (struct sockaddr*)&client.serv_addr, - client.serv_addr_len) == -1 ) { - Error(1000,"can't connect to '%s'",client.serv_addr.sun_path); - return 1; - } - - return 0; /* okay */ -} - -static int -DoDisconnect() -{ - if( client.sockfd != -1 ) { - close(client.sockfd); - client.sockfd = -1; - } - return 0; /* okay */ -} -/**************** - * NBYTES auf den aktuellen stream schreiben. - */ static int -DoWrite( void *buf, size_t nbytes ) +do_read( int fd, char *buffer, size_t bufsize, int *ret_nread ) { - size_t nleft = nbytes; - ssize_t nwritten; - - while( nleft > 0 ) { - /* FIXME: add EINTR handling */ - nwritten = write(client.sockfd, buf, nleft); - if( nwritten < 0 ) { - Error(1000,"error writing to server"); + int n; + fd_set rfds; + struct timeval tv; + int rc; + + *ret_nread = 0; + do { + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + tv.tv_sec = 1; + tv.tv_usec = 0; + if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) + return 0; /* timeout */ + if( rc == -1 ) { + log_error("select() error: %s\n", strerror(errno)); return -1; } - nleft -= nwritten; - buf = (char*)buf + nwritten; - } - return 0; -} - -static int -DoWriteStr( const char *s ) -{ - return DoWrite((char *)s, strlen(s) ); -} - - -static int -DoRead( void *buf, size_t buflen, size_t *ret_nread, int stop) -{ - size_t nleft = buflen; - int nread; - char *p; - - p = buf; - while( nleft > 0 ) { - /* FIXME: add EINTR handling */ - nread = read(client.sockfd, buf, stop? 1 : nleft); - if( nread < 0 ) { - Error(1000,"error reading from server"); - return -1; - } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - buf = (char*)buf + nread; - if( stop ) - for(; p < (char*)buf ; p++ ) - if( *p == '\n' ) - goto leave; - } - leave: - if( ret_nread ) - *ret_nread = buflen - nleft; - return 0; -} - -/**************** - * Like DoRead(), but append the received data to the given strgbuf. - * read a maximum of nbytes; - */ -static int -DoReadIntoStrgbuf( strgbuf_t *strgbuf, size_t nbytes, size_t *ret_nread) -{ - size_t ntotal, nleft; - int nread; - byte *p, buffer[1000]; - ntotal = 0; - nleft = nbytes; - while( nleft ) { - nread = read(client.sockfd, buffer, - nleft > DIM(buffer)? DIM(buffer) : nleft); - if( nread < 0 ) { - Error(1000,"error reading from server"); + do { + n = read(fd, buffer, bufsize ); + if( n >= 0 && n > bufsize ) + log_bug("bogus read from fd %d (n=%d)\n", fd, n ); + } while( n == -1 && errno == EINTR ); + if( n == -1 ) { + log_error("read error on fd %d: %s\n", fd, strerror(errno) ); return -1; } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - ntotal += nread; - /* ab in den stringbuffer */ - for(p=buffer; nread; nread--, p++ ) - PutStrgbuf(strgbuf, *p ); - } - - if( ret_nread ) - *ret_nread = ntotal; + } while( !n ); + *ret_nread = n; return 0; } -/**************** - * In retval wird das numerische argument nach OK zurückgegeben - */ -static int -DoRequest( char *request, long *retval ) -{ - if( DoWrite(request, strlen(request)) ) - return -1; - return DoWaitReply( retval ); -} - -static int -DoWaitReply( long *retval ) +int +ks_get_request( int fd, KS_TRANS *req ) { - char *p, buf[200]; /* enough room for messages */ - size_t nread; + char *p, *p2, buf[500]; + int nread, n; + int state = 0; + + req->err = 0; + req->data = NULL; + while( !do_read( fd, buf, DIM(buf)-1, &nread ) { + p = buf; + if( !state ) { + /* replace the trailing LF with a 0 */ + for(p2=p,n=0; n < nread && *p2 != '\n'; p2++ ) + ; + if( *p2 != '\n' ) { + req->err = KS_ERR_REQ_TOO_LONG; + break; + } + *p2++ = 0; + n++; + + /* now look at the request. Note that the isspace() will work + * because there is still a CR before the 0 */ + if( (p[0] == 'G' || p[0] == 'g') + && (p[1] == 'E' || p[1] == 'e') + && (p[2] == 'T' || p[2] == 't') && isspace( p[3] ) ) { + req->cmd = KS_REQ_GET; + p += 4; + } + else if( (p[0] == 'H' || p[0] == 'h') + && (p[1] == 'E' || p[1] == 'e') + && (p[2] == 'A' || p[2] == 'a') + && (p[3] == 'D' || p[3] == 'd') && isspace( p[4] ) ) { + req->cmd = KS_REQ_HEAD; + p += 5; + } + else if( (p[0] == 'H' || p[0] == 'h') + && (p[1] == 'E' || p[1] == 'e') + && (p[2] == 'L' || p[2] == 'l') + && (p[3] == 'P' || p[3] == 'p') && isspace( p[4] ) ) { + req->cmd = KS_REQ_HELP; + p += 5; + } + else + req->cmd = KS_REQ_UNKNOWN; + /* skip spaces, store args and remaining data */ + while( *p == ' ' || *p == '\t' ) + p++; + /* fixme: remove trailing blanks from args */ + req->args = p; + p = p2; /* p now points to the remaining n bytes in the buffer */ + state = 1; + } + if( state == 1 ) { + /* read the option lines */ + } - /* read but stop at the first newline */ - if( DoRead(buf, DIM(buf)-2, &nread, 1 ) ) - return -1; - buf[DIM(buf)-1] = 0; - /* fixme: should check, that we have the linefeed and otherwise - * perform a dummy read */ - if( p = strchr(buf, '\n') ) - *p = 0; - if( *buf == 'O' && buf[1] == 'K' && (buf[2]==' ' || !buf[2]) ) { - if( retval ) - *retval = buf[2]? strtol(buf+3, NULL, 10 ):0; - return 0; } - Error(0, "Server replied: %.60s", buf ); - return -1; } - - - - - - - - - - -#endif - - - |