See ChangeLog: Wed May 19 16:04:30 CEST 1999 Werner Koch
[gnupg.git] / g10 / ks-proto.c
index b862357..43abf46 100644 (file)
@@ -1,14 +1,14 @@
 /* ks-proto.c  keyserver protocol handling
  *     Copyright (C) 1998 Free Software Foundation, Inc.
  *
- * This file is part of GNUPG.
+ * This file is part of GnuPG.
  *
- * GNUPG is free software; you can redistribute it and/or modify
+ * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
  *
- * GNUPG is distributed in the hope that it will be useful,
+ * GnuPG is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *  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
-
-
-