ctx.c

来自「又一个DDNS 的源码」· C语言 代码 · 共 273 行

C
273
字号
/* *	DDNS v3 Client * *		Author:		Alan Yates <alany@ay.com.au> *		Version:	$Id: ctx.c,v 1.1.1.1 2002/07/19 11:47:20 alany Exp $ */#include "ctx.h"#include "sockio.h"#include "auth.h"#ifdef WIN32#include <windows.h>#else#include <unistd.h>#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#ifdef _DEBUG	#define DEBUG(x) x#else	#define DEBUG(x)#endif /* _DEBUG */static intctxsend(struct ddns3_ctx *c, char *cmd) { 	int ret;	ret = sprintf(c->buf, "%s\r\n", cmd);	ret = ddns3_sockio_write(c->sock, c->buf, ret);	if(ret < 0) return -1;	DEBUG( printf(">>> %s", c->buf); )	return 0;}static intrecvline(struct ddns3_ctx *c) {	int ret;	/* FIXME: we expect atomic line reception, fairly evil stuff */	ret = ddns3_sockio_read(c->sock, c->buf, DDNS3_BUF);	if(ret < 0) return -1;	c->buf[ret] = 0;	DEBUG( printf("<<< %s", c->buf); )	if(!strncmp(c->buf, "+OK",  3)) return T_OK;	if(!strncmp(c->buf, "-ERR", 4)) return T_ERR;	if(!strncmp(c->buf, "@RET", 4)) return T_RET;	if(!strncmp(c->buf, "DDNS", 4)) return T_DDNS;	if(!strncmp(&(c->buf[ret-3]), ".\r\n", 3)) return T_DOT;	return -1;}static intrecvlist(struct ddns3_ctx *c) {	int ret, i = 0;	char *p1, *p2, **lp = 0;	char handle[128], ip[16];	if(c->list) {		for(i = 0; c->list[i]; i++) free(c->list[i]);		free(c->list);		c->list = 0;	}	/* FIXME: we excpect atomic list reception, evil! */	ret = recvline(c);	if(ret != T_DOT) return -1;	c->buf[strlen(c->buf) - 3] = 0;	/* parse the list we get back, yuck */	i = 0;	p2 = c->buf;	lp = (char **) realloc(lp, (i + 1) * sizeof(char *));	while((p1 = strtok(p2, "\n"))) {		i += 2;		lp = (char **) realloc(lp, (i + 1) * sizeof(char *));		sscanf(p1, "%s%s", handle, ip);		lp[i-2] = strdup(handle);		lp[i-1] = strdup(ip);		lp[i] = 0;		p2 = 0;	}	c->list = lp;	return 0;}intddns3_ctx_new(struct ddns3_ctx **c, char *host, int port) {	/* allocate context */	*c = (struct ddns3_ctx *) calloc(1, sizeof(struct ddns3_ctx));	if(!(*c)) {		perror("calloc()");		return -1;	}	/* set URL */	sprintf((*c)->buf, "%s:%hd", host, (short) port);	(*c)->url = (char *) strdup((*c)->buf);	/* initialize sockets */	ddns3_sockio_init();	return 0;}intddns3_ctx_del(struct ddns3_ctx **c) {	int i = 0;	char *p;	/* just in case */	ddns3_sockio_close((*c)->sock);	if((*c)->url) free((*c)->url);	if((*c)->hello) free((*c)->hello);	if((*c)->list) {		for(p = (*c)->list[i]; p; p = (*c)->list[++i]) 			free(p);		free((*c)->list);	}	free(*c);	*c = 0;	/* clean up socket library */	ddns3_sockio_cleanup();	return 0;}intddns3_ctx_connect(struct ddns3_ctx *c) {	int ret;		/* connect to server */	DEBUG( printf("connect(%s)... ", c->url); )	ret = ddns3_sockio_connect(c->url);	if(ret < 0) return -1;	c->sock = ret;	DEBUG( printf("OK\n"); )		/* grab opening header */	ret = recvline(c);	if(ret != T_DDNS) return -1;	c->hello = strdup(c->buf);	return 0;}intddns3_ctx_disconnect(struct ddns3_ctx *c) {	int ret;		/* QUIT */	ret = ctxsend(c, "QUIT");	if(ret < 0) return -1;	/* reply */	ret = recvline(c);	if(ret != T_OK) return -1;	/* close socket */	ddns3_sockio_close(c->sock);	return 0;}intddns3_ctx_login(struct ddns3_ctx *c, char *auth, char *user, char *passwd) {	int ret;	char buf[4096];	/* build challenge command */	ret = ddns3_auth_makechallenge(c, auth, user, passwd);	if(ret < 0) return -1;	/* LOGIN */	strcpy(buf, c->buf);	ret = ctxsend(c, buf);	if(ret < 0) return -1;	/* reply */	ret = recvline(c);	if(ret != T_OK) return -1;	return 0;}intddns3_ctx_logout(struct ddns3_ctx *c) {	int ret;		/* LOGOUT */	ret = ctxsend(c, "LOGOUT");	if(ret < 0) return -1;	/* reply */	ret = recvline(c);	if(ret != T_OK) return -1;	return 0;}intddns3_ctx_list(struct ddns3_ctx *c) {	int ret;		/* LIST */	ret = ctxsend(c, "LIST");	if(ret < 0) return -1;	/* get returned value */	ret = recvline(c);	if(ret != T_RET) return -1;	ret = recvlist(c);	if(ret < 0) return -1;	return 0;}intddns3_ctx_set(struct ddns3_ctx *c, char *handle, char *ip) {	int ret;	char buf[4096];		/* SET */	ret = sprintf(buf, "SET %s %s", handle, ip);	ret = ctxsend(c, buf);	if(ret < 0) return -1;	/* reply */	ret = recvline(c);	if(ret != T_OK) return -1;	return 0;}intddns3_ctx_guess(struct ddns3_ctx *c, char *handle, int type) {	int ret, i = 0;	char buf[4096], ipbuf[32], *p, *q;		/* SET */	switch(type) {		case GUESS_LOCAL:			ret = ddns3_sockio_getlocalip(c->sock, ipbuf, 32);			break;		case GUESS_REMOTE:			if(!(p = strstr(c->hello, "sourceIP{"))) return -1;			if(!(q = strstr(p, "}"))) return -1;			for(p += 9; p < q; p++) ipbuf[i++] = *p;			ipbuf[i] = 0;			break;		default:			return -1;	}	ret = sprintf(buf, "SET %s %s", handle, ipbuf);	ret = ctxsend(c, buf);	if(ret < 0) return -1;	/* reply */	ret = recvline(c);	if(ret != T_OK) return -1;	return 0;}

⌨️ 快捷键说明

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