📄 lib_api.c
字号:
/* $Id: lib_api.c,v 1.12 2001/08/04 20:55:55 jm Exp $ * Dynamics API library general support routines implementation * * Dynamic hierarchial IP tunnel * Copyright (C) 1998-2001, Dynamics group * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */#ifndef __USE_SVID#define __USE_SVID#endif#include "config.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <assert.h>#include <errno.h>#include "../other/fixed_fd_zero.h"#include "lib_api.h"#ifdef DYN_TARGET_WINDOWS#include <sys/socket.h>#include "../other/windows_extra.h"#endif#define ASSERT assert#define TMP_PREFIX "dyn_lib"#define TMP_DIR NULL#define SOCK_PERM 0600#define ERROR_STRING_COUNT 13static char *error_codes[ERROR_STRING_COUNT] = { "success", "function not permitted", "illegal parameters", "undefined error", "agent unreachable", "call timeouted", "insufficient result buffer space", "function not supported", "function not available", "another call in progress", "cancelled", "failed", "system error" };static char agent_path[PATH_SIZE];static char *tmp_dir = NULL;static char *tmp_prefix = NULL;static int sock_perm;/* * Initialize library * Parameters: * agent - path to mobility agent * tmpdir - directory for temporary api domain sockets * tmppfx - prefix for temporary api domain socket name * sockperm - permissions for api socket * Returns: * API_FAILED - error in initialization * API_SUCCESS - success * */int lib_init(char *agent, char *tmpdir, char *tmppfx, int sockperm){ if (agent != NULL) { strncpy(agent_path, agent, PATH_SIZE); agent_path[PATH_SIZE - 1] = '\0'; } if (tmpdir != NULL) tmp_dir = tmpdir; else tmp_dir = TMP_DIR; if (tmppfx != NULL) tmp_prefix = tmppfx; else tmp_prefix = TMP_PREFIX; if (sockperm != 0) sock_perm = sockperm; else sock_perm = SOCK_PERM; return API_SUCCESS;}/* * Send api call * Parameters: * s - socket descriptor * func - function code [msg.code] * data - data storage [msg.params] * datalen - length of data [msg.length] * Returns: * -1 - error * 0 - success */static int send_call(int s, int func, char *data, int datalen){ struct api_msg msg; dyn_api_sockaddr addr; socklen_t addrlen; ASSERT(datalen < API_DATA_SIZE); msg.type = API_CALL_MSG; msg.code = func; if (datalen > API_DATA_SIZE) datalen = API_DATA_SIZE - 1; if (data == NULL) datalen = 0; memcpy(msg.params, data, datalen); msg.length = datalen;#ifdef DYN_TARGET_LINUX strncpy(addr.sun_path, agent_path, sizeof(addr.sun_path)); addr.sun_path[sizeof(addr.sun_path) - 1] = '\0'; addr.sun_family = AF_LOCAL; addrlen = sizeof(addr.sun_family) + strlen(agent_path);#endif#ifdef DYN_TARGET_WINDOWS memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl((127 << 24) | 1); addr.sin_port = htons(API_UDP_PORT_RW); addrlen = sizeof(addr);#endif return api_send(s, &addr, addrlen, &msg);}/* * Wait timeout seconds for data in s nd read it to msg. * Parameters: * s - socket descriptor * timeout - timeout value. If negative -> block forever * msg - storage for received message * Returns: * -1 - error * 0 - timeout * 1 - success */static int timed_receive(int s, int timeout, struct api_msg *msg){ fd_set set; struct timeval tv; dyn_api_sockaddr addr; int i, r; unsigned int tmp = 0; ASSERT(s != -1 && msg != NULL); FD_ZERO(&set); FD_SET(s, &set); tv.tv_sec = timeout; tv.tv_usec = 0; if ((i = select(FD_SETSIZE, &set, NULL,NULL, (timeout < 0)? NULL : &tv)) == 1) { r = api_receive(s, &addr, &tmp, msg); return (r == 0) ? 1 : -1; } else return (errno==EINTR)? API_CANCELLED : API_ERROR;}/* * Perform an API call and wait for response. * Parameters: * func - function code for the call * params - parameters for API call * param_len - length of parameters * timeout - reply wait timeout is seconds (-1 -> wait forever) * msg - storage for reply message * Returns: API_XXXX depending on result */int perform_call(int func, void *params, int param_len, int timeout, struct api_msg *msg){ int s, i; ASSERT(msg != NULL); /* send call */#ifdef DYN_TARGET_LINUX s = api_open_socket(NULL, NULL, NULL, sock_perm); if (s < 0) return API_ERROR;#endif#ifdef DYN_TARGET_WINDOWS s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) return API_ERROR;#endif if (send_call(s, func, params, param_len) < 0) { api_close_socket(s); return API_UNREACHABLE; } /* receive reply */ i = timed_receive(s, timeout, msg); api_close_socket(s); switch (i) { case -1: return API_ERROR; case 0: return API_TIMEOUT; case 1: return msg->code; } return API_FAILED;}/* * Returns string representation for error code. */char *get_error_string(int err){ static char dummy[] = ""; err = -err; if (err < 0 || err >= ERROR_STRING_COUNT) return dummy; return error_codes[err];}/* * Return pointer to current agent path. */char *get_agent_path(void){ return agent_path;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -