]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/uxagentc.c
Note the interaction of jump lists and -cleanup.
[PuTTY.git] / unix / uxagentc.c
index 326ee66b832439e35cb40a471339bc989074669c..ffc5879cfbc0f5dba078f56ab72f2690908963cc 100644 (file)
@@ -23,8 +23,8 @@ int agent_exists(void)
     return FALSE;
 }
 
-static tree234 *agent_connections;
-struct agent_connection {
+static tree234 *agent_pending_queries;
+struct agent_pending_query {
     int fd;
     char *retbuf;
     char sizebuf[4];
@@ -34,8 +34,8 @@ struct agent_connection {
 };
 static int agent_conncmp(void *av, void *bv)
 {
-    struct agent_connection *a = (struct agent_connection *) av;
-    struct agent_connection *b = (struct agent_connection *) bv;
+    agent_pending_query *a = (agent_pending_query *) av;
+    agent_pending_query *b = (agent_pending_query *) bv;
     if (a->fd < b->fd)
        return -1;
     if (a->fd > b->fd)
@@ -45,7 +45,7 @@ static int agent_conncmp(void *av, void *bv)
 static int agent_connfind(void *av, void *bv)
 {
     int afd = *(int *) av;
-    struct agent_connection *b = (struct agent_connection *) bv;
+    agent_pending_query *b = (agent_pending_query *) bv;
     if (afd < b->fd)
        return -1;
     if (afd > b->fd)
@@ -59,7 +59,7 @@ static int agent_connfind(void *av, void *bv)
  * (conn->retbuf non-NULL and filled with something useful) or has
  * failed totally (conn->retbuf is NULL).
  */
-static int agent_try_read(struct agent_connection *conn)
+static int agent_try_read(agent_pending_query *conn)
 {
     int ret;
 
@@ -90,13 +90,21 @@ static int agent_try_read(struct agent_connection *conn)
     return 1;
 }
 
+void agent_cancel_query(agent_pending_query *conn)
+{
+    uxsel_del(conn->fd);
+    close(conn->fd);
+    del234(agent_pending_queries, conn);
+    sfree(conn);
+}
+
 static int agent_select_result(int fd, int event)
 {
-    struct agent_connection *conn;
+    agent_pending_query *conn;
 
     assert(event == 1);                       /* not selecting for anything but R */
 
-    conn = find234(agent_connections, &fd, agent_connfind);
+    conn = find234(agent_pending_queries, &fd, agent_connfind);
     if (!conn) {
        uxsel_del(fd);
        return 1;
@@ -111,24 +119,22 @@ static int agent_select_result(int fd, int event)
      * of that passes to the callback.)
      */
     conn->callback(conn->callback_ctx, conn->retbuf, conn->retlen);
-    uxsel_del(fd);
-    close(fd);
-    del234(agent_connections, conn);
-    sfree(conn);
+    agent_cancel_query(conn);
     return 0;
 }
 
-int agent_query(void *in, int inlen, void **out, int *outlen,
-               void (*callback)(void *, void *, int), void *callback_ctx)
+agent_pending_query *agent_query(
+    void *in, int inlen, void **out, int *outlen,
+    void (*callback)(void *, void *, int), void *callback_ctx)
 {
     char *name;
     int sock;
     struct sockaddr_un addr;
     int done;
-    struct agent_connection *conn;
+    agent_pending_query *conn;
 
     name = getenv("SSH_AUTH_SOCK");
-    if (!name)
+    if (!name || strlen(name) >= sizeof(addr.sun_path))
        goto failure;
 
     sock = socket(PF_UNIX, SOCK_STREAM, 0);
@@ -140,7 +146,7 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
     cloexec(sock);
 
     addr.sun_family = AF_UNIX;
-    strncpy(addr.sun_path, name, sizeof(addr.sun_path));
+    strcpy(addr.sun_path, name);
     if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        close(sock);
        goto failure;
@@ -155,7 +161,7 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
        done += ret;
     }
 
-    conn = snew(struct agent_connection);
+    conn = snew(agent_pending_query);
     conn->fd = sock;
     conn->retbuf = conn->sizebuf;
     conn->retsize = 4;
@@ -179,7 +185,7 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
         *out = conn->retbuf;
         *outlen = conn->retlen;
         sfree(conn);
-        return 1;
+        return NULL;
     }
 
     /*
@@ -188,15 +194,15 @@ int agent_query(void *in, int inlen, void **out, int *outlen,
      * response hasn't been received yet, and call the callback when
      * select_result comes back to us.
      */
-    if (!agent_connections)
-       agent_connections = newtree234(agent_conncmp);
-    add234(agent_connections, conn);
+    if (!agent_pending_queries)
+       agent_pending_queries = newtree234(agent_conncmp);
+    add234(agent_pending_queries, conn);
 
     uxsel_set(sock, 1, agent_select_result);
-    return 0;
+    return conn;
 
     failure:
     *out = NULL;
     *outlen = 0;
-    return 1;
+    return NULL;
 }