⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uxagentc.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
字号:
/* * SSH agent client code. */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <unistd.h>#include <sys/socket.h>#include <sys/un.h>#include "putty.h"#include "misc.h"#include "tree234.h"#include "puttymem.h"#define GET_32BIT(cp) \    (((unsigned long)(unsigned char)(cp)[0] << 24) | \    ((unsigned long)(unsigned char)(cp)[1] << 16) | \    ((unsigned long)(unsigned char)(cp)[2] << 8) | \    ((unsigned long)(unsigned char)(cp)[3]))int agent_exists(void){    if (getenv("SSH_AUTH_SOCK") != NULL)	return TRUE;    return FALSE;}static tree234 *agent_connections;struct agent_connection {    int fd;    char *retbuf;    char sizebuf[4];    int retsize, retlen;    void (*callback)(void *, void *, int);    void *callback_ctx;};static int agent_conncmp(void *av, void *bv){    struct agent_connection *a = (struct agent_connection *) av;    struct agent_connection *b = (struct agent_connection *) bv;    if (a->fd < b->fd)	return -1;    if (a->fd > b->fd)	return +1;    return 0;}static int agent_connfind(void *av, void *bv){    int afd = *(int *) av;    struct agent_connection *b = (struct agent_connection *) bv;    if (afd < b->fd)	return -1;    if (afd > b->fd)	return +1;    return 0;}static int agent_select_result(int fd, int event){    int ret;    struct agent_connection *conn;    assert(event == 1);		       /* not selecting for anything but R */    conn = find234(agent_connections, &fd, agent_connfind);    if (!conn) {	uxsel_del(fd);	return 1;    }    ret = read(fd, conn->retbuf+conn->retlen, conn->retsize-conn->retlen);    if (ret <= 0) {	if (conn->retbuf != conn->sizebuf) sfree(conn->retbuf);	conn->retbuf = NULL;	conn->retlen = 0;	goto done;    }    conn->retlen += ret;    if (conn->retsize == 4 && conn->retlen == 4) {	conn->retsize = GET_32BIT(conn->retbuf);	if (conn->retsize <= 0) {	    conn->retbuf = NULL;	    conn->retlen = 0;	    goto done;	}	conn->retsize += 4;	assert(conn->retbuf == conn->sizebuf);	conn->retbuf = snewn(conn->retsize, char);	memcpy(conn->retbuf, conn->sizebuf, 4);    }    if (conn->retlen < conn->retsize)	return 0;		       /* more data to come */    done:    /*     * We have now completed the agent query. Do the callback, and     * clean up. (Of course we don't free retbuf, since ownership     * 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);    return 0;}int 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;    name = getenv("SSH_AUTH_SOCK");    if (!name)	goto failure;    sock = socket(PF_UNIX, SOCK_STREAM, 0);    if (sock < 0) {	perror("socket(PF_UNIX)");	exit(1);    }    addr.sun_family = AF_UNIX;    strncpy(addr.sun_path, name, sizeof(addr.sun_path));    if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {	close(sock);	goto failure;    }    for (done = 0; done < inlen ;) {	int ret = write(sock, (char *)in + done, inlen - done);	if (ret <= 0) {	    close(sock);	    goto failure;	}	done += ret;    }    if (!agent_connections)	agent_connections = newtree234(agent_conncmp);    conn = snew(struct agent_connection);    conn->fd = sock;    conn->retbuf = conn->sizebuf;    conn->retsize = 4;    conn->retlen = 0;    conn->callback = callback;    conn->callback_ctx = callback_ctx;    add234(agent_connections, conn);    uxsel_set(sock, 1, agent_select_result);    return 0;    failure:    *out = NULL;    *outlen = 0;    return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -