• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C++ RDEBUG函数代码示例

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

本文整理汇总了C++中RDEBUG函数的典型用法代码示例。如果您正苦于以下问题:C++ RDEBUG函数的具体用法?C++ RDEBUG怎么用?C++ RDEBUG使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。



在下文中一共展示了RDEBUG函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。

示例1: mod_accounting

/*
 *	Store logins in the RADIUS utmp file.
 */
static rlm_rcode_t mod_accounting(void *instance, REQUEST *request)
{
	rlm_rcode_t	rcode = RLM_MODULE_OK;
	struct radutmp	ut, u;
	vp_cursor_t	cursor;
	VALUE_PAIR	*vp;
	int		status = -1;
	int		protocol = -1;
	time_t		t;
	int		fd = -1;
	int		port_seen = 0;
	int		off;
	rlm_radutmp_t	*inst = instance;
	char		ip_name[32]; /* 255.255.255.255 */
	char const	*nas;
	NAS_PORT	*cache;
	int		r;
	
	char		*filename = NULL;
	char		*expanded = NULL;

	if (request->packet->src_ipaddr.af != AF_INET) {
		DEBUG("rlm_radutmp: IPv6 not supported!");
		return RLM_MODULE_NOOP;
	}

	/*
	 *	Which type is this.
	 */
	if ((vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE, 0, TAG_ANY)) == NULL) {
		RDEBUG("No Accounting-Status-Type record.");
		return RLM_MODULE_NOOP;
	}
	status = vp->vp_integer;

	/*
	 *	Look for weird reboot packets.
	 *
	 *	ComOS (up to and including 3.5.1b20) does not send
	 *	standard PW_STATUS_ACCOUNTING_XXX messages.
	 *
	 *	Check for:  o no Acct-Session-Time, or time of 0
	 *		    o Acct-Session-Id of "00000000".
	 *
	 *	We could also check for NAS-Port, that attribute
	 *	should NOT be present (but we don't right now).
	 */
	if ((status != PW_STATUS_ACCOUNTING_ON) &&
	    (status != PW_STATUS_ACCOUNTING_OFF)) do {
		int check1 = 0;
		int check2 = 0;

		if ((vp = pairfind(request->packet->vps, PW_ACCT_SESSION_TIME, 0, TAG_ANY))
		     == NULL || vp->vp_date == 0)
			check1 = 1;
		if ((vp = pairfind(request->packet->vps, PW_ACCT_SESSION_ID, 0, TAG_ANY))
		     != NULL && vp->length == 8 &&
		     memcmp(vp->vp_strvalue, "00000000", 8) == 0)
			check2 = 1;
		if (check1 == 0 || check2 == 0) {
			break;
		}
		INFO("rlm_radutmp: converting reboot records.");
		if (status == PW_STATUS_STOP)
			status = PW_STATUS_ACCOUNTING_OFF;
		if (status == PW_STATUS_START)
			status = PW_STATUS_ACCOUNTING_ON;
	} while(0);

	time(&t);
	memset(&ut, 0, sizeof(ut));
	ut.porttype = 'A';
	ut.nas_address = htonl(INADDR_NONE);

	/*
	 *	First, find the interesting attributes.
	 */
	for (vp = paircursor(&cursor, &request->packet->vps);
	     vp;
	     vp = pairnext(&cursor)) {
		if (!vp->da->vendor) switch (vp->da->attr) {
			case PW_LOGIN_IP_HOST:
			case PW_FRAMED_IP_ADDRESS:
				ut.framed_address = vp->vp_ipaddr;
				break;
			case PW_FRAMED_PROTOCOL:
				protocol = vp->vp_integer;
				break;
			case PW_NAS_IP_ADDRESS:
				ut.nas_address = vp->vp_ipaddr;
				break;
			case PW_NAS_PORT:
				ut.nas_port = vp->vp_integer;
				port_seen = 1;
				break;
			case PW_ACCT_DELAY_TIME:
				ut.delay = vp->vp_integer;
//.........这里部分代码省略.........
开发者ID:dpocock,项目名称:freeradius-server,代码行数:101,代码来源:rlm_radutmp.c


示例2: eapsoh_mstlv

/**
 * @brief Parses the MS-SOH type/value (note: NOT type/length/value) data and
 * 	update the sohvp list
 *
 * See section 2.2.4 of MS-SOH. Because there's no "length" field we CANNOT just skip
 * unknown types; we need to know their length ahead of time. Therefore, we abort
 * if we find an unknown type. Note that sohvp may still have been modified in the
 * failure case.
 *
 * @param request Current request
 * @param p binary blob
 * @param data_len length of blob
 * @return 1 on success, 0 on failure
 */
static int eapsoh_mstlv(REQUEST *request, uint8_t const *p, unsigned int data_len)
{
	VALUE_PAIR *vp;
	uint8_t c;
	int t;
	char *q;

	while (data_len > 0) {
		c = *p++;
		data_len--;

		switch (c) {
			case 1:
				/* MS-Machine-Inventory-Packet
				 * MS-SOH section 2.2.4.1
				 */
				if (data_len < 18) {
					RDEBUG("insufficient data for MS-Machine-Inventory-Packet");
					return 0;
				}
				data_len -= 18;

				vp = pairmake_packet("SoH-MS-Machine-OS-vendor", "Microsoft", T_OP_EQ);
				if (!vp) return 0;

				vp = pairmake_packet("SoH-MS-Machine-OS-version", NULL, T_OP_EQ);
				if (!vp) return 0;

				vp->vp_integer = soh_pull_be_32(p); p+=4;

				vp = pairmake_packet("SoH-MS-Machine-OS-release", NULL, T_OP_EQ);
				if (!vp) return 0;

				vp->vp_integer = soh_pull_be_32(p); p+=4;

				vp = pairmake_packet("SoH-MS-Machine-OS-build", NULL, T_OP_EQ);
				if (!vp) return 0;

				vp->vp_integer = soh_pull_be_32(p); p+=4;

				vp = pairmake_packet("SoH-MS-Machine-SP-version", NULL, T_OP_EQ);
				if (!vp) return 0;

				vp->vp_integer = soh_pull_be_16(p); p+=2;

				vp = pairmake_packet("SoH-MS-Machine-SP-release", NULL, T_OP_EQ);
				if (!vp) return 0;

				vp->vp_integer = soh_pull_be_16(p); p+=2;

				vp = pairmake_packet("SoH-MS-Machine-Processor", NULL, T_OP_EQ);
				if (!vp) return 0;

				vp->vp_integer = soh_pull_be_16(p); p+=2;
				break;

			case 2:
				/* MS-Quarantine-State - FIXME: currently unhandled
				 * MS-SOH 2.2.4.1
				 *
				 * 1 byte reserved
				 * 1 byte flags
				 * 8 bytes NT Time field (100-nanosec since 1 Jan 1601)
				 * 2 byte urilen
				 * N bytes uri
				 */
				p += 10;
				t = soh_pull_be_16(p);	/* t == uri len */
				p += 2;
				p += t;
				data_len -= 12 + t;
				break;

			case 3:
				/* MS-Packet-Info
				 * MS-SOH 2.2.4.3
				 */
				RDEBUG3("SoH MS-Packet-Info %s vers=%i", *p & 0x10 ? "request" : "response", *p & 0xf);
				p++;
				data_len--;
				break;

			case 4:
				/* MS-SystemGenerated-Ids - FIXME: currently unhandled
				 * MS-SOH 2.2.4.4
				 *
//.........这里部分代码省略.........
开发者ID:AirspeedTelecom,项目名称:freeradius,代码行数:101,代码来源:soh.c


示例3: CC_HINT

/*
 *	Authenticate the user with the given password.
 */
static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request)
{
	rlm_smsotp_t *inst = instance;
	VALUE_PAIR *state;
	int bufsize;
	int *fdp;
	rlm_rcode_t rcode = RLM_MODULE_FAIL;
	char buffer[1000];
	char output[1000];

	fdp = fr_connection_get(inst->pool);
	if (!fdp) return RLM_MODULE_FAIL;

	/* Get greeting */
	bufsize = read_all(fdp, buffer, sizeof(buffer));
	if (bufsize <= 0) {
		REDEBUG("Failed reading from socket");
		goto done;
	}

	/*
	 *  Look for the 'state' attribute.
	 */
#define WRITE_ALL(_a,_b,_c) if (write_all(_a,_b,_c) < 0) goto done;
	state = fr_pair_find_by_num(request->packet->vps, PW_STATE, 0, TAG_ANY);
	if (state) {
		RDEBUG("Found reply to access challenge");

		/* send username */
		snprintf(output, sizeof(output), "check otp for %s\n",
			 request->username->vp_strvalue);
		WRITE_ALL(fdp, output, strlen(output));

		(void) read_all(fdp, buffer, sizeof(buffer));

		/* send password */
		snprintf(output, sizeof(output), "user otp is %s\n",
			 request->password->vp_strvalue);
		WRITE_ALL(fdp, output, strlen(output));

		(void) read_all(fdp, buffer, sizeof(buffer));

		/* set uuid */
		snprintf(output, sizeof(output), "otp id is %s\n",
			 state->vp_strvalue);
		WRITE_ALL(fdp, output, strlen(output));

		(void) read_all(fdp, buffer, sizeof(buffer));

		/* now check the otp */
		WRITE_ALL(fdp, "get check result\n", 17);

		(void) read_all(fdp, buffer, sizeof(buffer));

		/* end the sesssion */
		WRITE_ALL(fdp, "quit\n", 5);

		RDEBUG("answer is %s", buffer);
		if (strcmp(buffer,"OK") == 0) {
			rcode = RLM_MODULE_OK;
		}

		goto done;
	}

	RDEBUG("Generating OTP");

	/* set username */
	snprintf(output, sizeof(output), "generate otp for %s\n",
		 request->username->vp_strvalue);
	WRITE_ALL(fdp, output, strlen(output));

	(void) read_all(fdp, buffer, sizeof(buffer));

	/* end the sesssion */
	WRITE_ALL(fdp, "quit\n", 5);

	RDEBUG("Unique ID is %s", buffer);

	/* check the return string */
	if (strcmp(buffer,"FAILED") == 0) { /* smsotp script returns a error */
		goto done;
	}

	/*
	 *	Create the challenge, and add it to the reply.
	 */

	pair_make_reply("Reply-Message", inst->challenge, T_OP_EQ);
	pair_make_reply("State", buffer, T_OP_EQ);

	/*
	 *  Mark the packet as an Access-Challenge packet.
	 *
	 *  The server will take care of sending it to the user.
	 */
	request->reply->code = PW_CODE_ACCESS_CHALLENGE;
//.........这里部分代码省略.........
开发者ID:k-paulius,项目名称:freeradius-server,代码行数:101,代码来源:rlm_smsotp.c


示例4: CC_HINT

/*
 *	Allocate an IP number from the pool.
 */
static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request)
{
	rlm_sqlippool_t *inst = (rlm_sqlippool_t *) instance;
	char allocation[MAX_STRING_LEN];
	int allocation_len;
	uint32_t ip_allocation;
	VALUE_PAIR *vp;
	rlm_sql_handle_t *handle;
	fr_ipaddr_t ipaddr;
	time_t now;

	/*
	 *	If there is a Framed-IP-Address attribute in the reply do nothing
	 */
	if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY) != NULL) {
		RDEBUG("Framed-IP-Address already exists");

		return do_logging(request, inst->log_exists, RLM_MODULE_NOOP);
	}

	if (pairfind(request->config_items, PW_POOL_NAME, 0, TAG_ANY) == NULL) {
		RDEBUG("No Pool-Name defined");

		return do_logging(request, inst->log_nopool, RLM_MODULE_NOOP);
	}

	handle = inst->sql_inst->sql_get_socket(inst->sql_inst);
	if (!handle) {
		REDEBUG("cannot get sql connection");
		return RLM_MODULE_FAIL;
	}

	if (inst->sql_inst->sql_set_user(inst->sql_inst, request, NULL) < 0) {
		return RLM_MODULE_FAIL;
	}

	/*
	 *	Limit the number of clears we do.  There are minor
	 *	race conditions for the check, but so what.  The
	 *	actual work is protected by a transaction.  The idea
	 *	here is that if we're allocating 100 IPs a second,
	 *	we're only do 1 CLEAR per second.
	 */
	now = time(NULL);
	if (inst->last_clear < now) {
		inst->last_clear = now;

		DO(allocate_begin);
		DO(allocate_clear);
		DO(allocate_commit);
	}

	DO(allocate_begin);

	allocation_len = sqlippool_query1(allocation, sizeof(allocation),
					  inst->allocate_find, handle,
					  inst, request, (char *) NULL, 0);

	/*
	 *	Nothing found...
	 */
	if (allocation_len == 0) {
		DO(allocate_commit);

		/*
		 *Should we perform pool-check ?
		 */
		if (inst->pool_check && *inst->pool_check) {

			/*
			 *Ok, so the allocate-find query found nothing ...
			 *Let's check if the pool exists at all
			 */
			allocation_len = sqlippool_query1(allocation, sizeof(allocation),
							  inst->pool_check, handle, inst, request,
							  (char *) NULL, 0);

			inst->sql_inst->sql_release_socket(inst->sql_inst, handle);

			if (allocation_len) {

				/*
				 *	Pool exists after all... So,
				 *	the failure to allocate the IP
				 *	address was most likely due to
				 *	the depletion of the pool. In
				 *	that case, we should return
				 *	NOTFOUND
				 */
				RDEBUG("pool appears to be full");
				return do_logging(request, inst->log_failed, RLM_MODULE_NOTFOUND);

			}

			/*
			 *	Pool doesn't exist in the table. It
			 *	may be handled by some other instance of
//.........这里部分代码省略.........
开发者ID:amirdaly,项目名称:freeradius-server,代码行数:101,代码来源:rlm_sqlippool.c


示例5: radius_compare_vps

/** Compares check and vp by value.
 *
 * Does not call any per-attribute comparison function, but does honour
 * check.operator. Basically does "vp.value check.op check.value".
 *
 * @param request Current request.
 * @param check rvalue, and operator.
 * @param vp lvalue.
 * @return 0 if check and vp are equal, -1 if vp value is less than check value, 1 is vp value is more than check
 *	value, -2 on error.
 */
int radius_compare_vps(REQUEST *request, VALUE_PAIR *check, VALUE_PAIR *vp)
{
	int ret = 0;

	/*
	 *      Check for =* and !* and return appropriately
	 */
	if (check->op == T_OP_CMP_TRUE)  return 0;
	if (check->op == T_OP_CMP_FALSE) return 1;

#ifdef HAVE_REGEX_H
	if (check->op == T_OP_REG_EQ) {
		int compare;
		regex_t reg;
		char value[1024];
		regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];

		vp_prints_value(value, sizeof(value), vp, -1);

		/*
		 *	Include substring matches.
		 */
		compare = regcomp(&reg, check->vp_strvalue, REG_EXTENDED);
		if (compare != 0) {
			char buffer[256];
			regerror(compare, &reg, buffer, sizeof(buffer));

			RDEBUG("Invalid regular expression %s: %s", check->vp_strvalue, buffer);
			return -2;
		}

		memset(&rxmatch, 0, sizeof(rxmatch));	/* regexec does not seem to initialise unused elements */
		compare = regexec(&reg, value, REQUEST_MAX_REGEX + 1, rxmatch, 0);
		regfree(&reg);
		rad_regcapture(request, compare, value, rxmatch);

		ret = (compare == 0) ? 0 : -1;
		goto finish;
	}

	if (check->op == T_OP_REG_NE) {
		int compare;
		regex_t reg;
		char value[1024];
		regmatch_t rxmatch[REQUEST_MAX_REGEX + 1];

		vp_prints_value(value, sizeof(value), vp, -1);

		/*
		 *	Include substring matches.
		 */
		compare = regcomp(&reg, check->vp_strvalue, REG_EXTENDED);
		if (compare != 0) {
			char buffer[256];
			regerror(compare, &reg, buffer, sizeof(buffer));

			RDEBUG("Invalid regular expression %s: %s", check->vp_strvalue, buffer);
			return -2;
		}
		compare = regexec(&reg, value,  REQUEST_MAX_REGEX + 1, rxmatch, 0);
		regfree(&reg);

		ret = (compare != 0) ? 0 : -1;
	}
#endif

	/*
	 *	Attributes must be of the same type.
	 *
	 *	FIXME: deal with type mismatch properly if one side contain
	 *	ABINARY, OCTETS or STRING by converting the other side to
	 *	a string
	 *
	 */
	if (vp->da->type != check->da->type) return -1;

	/*
	 *	Tagged attributes are equal if and only if both the
	 *	tag AND value match.
	 */
	if (check->da->flags.has_tag) {
		ret = ((int) vp->tag) - ((int) check->tag);
		goto finish;
	}

	/*
	 *	Not a regular expression, compare the types.
	 */
	switch(check->da->type) {
//.........这里部分代码省略.........
开发者ID:accense,项目名称:freeradius-server,代码行数:101,代码来源:valuepair.c


示例6: redisn_groupcmp

static int redisn_groupcmp(void *instance, REQUEST *request, VALUE_PAIR *request_vp, VALUE_PAIR *check,
			VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs)
{
	REDISSOCK *redis_socket;
	REDIS_INST *inst = instance;
	char redisnusername[MAX_STRING_LEN];
	REDISN_GROUPLIST *group_list, *group_list_tmp;

	check_pairs = check_pairs;
	reply_pairs = reply_pairs;
	request_vp = request_vp;

	RDEBUG("redisn_groupcmp");
	if (!check || !check->vp_strvalue || !check->length){
		RDEBUG("redisn_groupcmp: Illegal group name");
		return 1;
	}
	if (!request){
		RDEBUG("redisn_groupcmp: NULL request");
		return 1;
	}
	/*
	 * Set, escape, and check the user attr here
	 */
	if (redisn_set_user(inst, request, redisnusername, NULL) < 0)
		return 1;

	/*
	 *	Get a socket for this lookup
	 */
	redis_socket = redisn_get_socket(inst);
	if (redis_socket == NULL) {
		/* Remove the username we (maybe) added above */
		pairdelete(&request->packet->vps, PW_REDIS_USER_NAME, 0, TAG_ANY);
		return 1;
	}

	/*
	 *	Get the list of groups this user is a member of
	 */
	if (redisn_get_grouplist(inst, redis_socket, request, &group_list) < 0) {
		radlog_request(L_ERR, 0, request,
			       "Error getting group membership");
		/* Remove the username we (maybe) added above */
		pairdelete(&request->packet->vps, PW_REDIS_USER_NAME, 0, TAG_ANY);
		redisn_release_socket(inst, redis_socket);
		return 1;
	}

	for (group_list_tmp = group_list; group_list_tmp != NULL; group_list_tmp = group_list_tmp->next) {
		if (strcmp(group_list_tmp->groupname, check->vp_strvalue) == 0){
			RDEBUG("redisn_groupcmp finished: User is a member of group %s",
			       check->vp_strvalue);
			/* Free the grouplist */
			redisn_grouplist_free(&group_list);
			/* Remove the username we (maybe) added above */
			pairdelete(&request->packet->vps, PW_REDIS_USER_NAME, 0, TAG_ANY);
			redisn_release_socket(inst, redis_socket);
			return 0;
		}
	}

	/* Free the grouplist */
	redisn_grouplist_free(&group_list);
	/* Remove the username we (maybe) added above */
	pairdelete(&request->packet->vps, PW_REDIS_USER_NAME, 0, TAG_ANY);
	redisn_release_socket(inst,redis_socket);

	RDEBUG("redisn_groupcmp finished: User is NOT a member of group %s",
	       check->vp_strvalue);

	return 1;
}
开发者ID:mguesdon,项目名称:freeradius-server,代码行数:73,代码来源:rlm_redisn.c


示例7: radius_start_program

/** Start a process
 *
 * @param cmd Command to execute. This is parsed into argv[] parts,
 * 	then each individual argv part is xlat'ed.
 * @param request Current reuqest
 * @param exec_wait set to 1 if you want to read from or write to child
 * @param[in,out] input_fd pointer to int, receives the stdin file.
 * 	descriptor. Set to NULL and the child will have /dev/null on stdin
 * @param[in,out] output_fd pinter to int, receives the stdout file
 * 	descriptor. Set to NULL and child will have /dev/null on stdout.
 * @param input_pairs list of value pairs - these will be put into
 * 	the environment variables of the child.
 * @param shell_escape values before passing them as arguments.
 * @return PID of the child process, -1 on error.
 */
pid_t radius_start_program(char const *cmd, REQUEST *request, bool exec_wait,
			   int *input_fd, int *output_fd,
			   VALUE_PAIR *input_pairs, bool shell_escape)
{
#ifndef __MINGW32__
	char *p;
	VALUE_PAIR *vp;
	int n;
	int to_child[2] = {-1, -1};
	int from_child[2] = {-1, -1};
	pid_t pid;
#endif
	int argc;
	int i;
	char *argv[MAX_ARGV];
	char argv_buf[4096];
#define MAX_ENVP 1024
	char *envp[MAX_ENVP];
	int envlen = 0;

	argc = rad_expand_xlat(request, cmd, MAX_ARGV, argv, true, sizeof(argv_buf), argv_buf);
	if (argc <= 0) {
		RDEBUG("invalid command line '%s'.", cmd);
		return -1;
	}


#ifndef NDEBUG
	if (debug_flag > 2) {
		RDEBUG3("executing cmd %s", cmd);
		for (i = 0; i < argc; i++) {
			RDEBUG3("\t[%d] %s", i, argv[i]);
		}
	}
#endif

#ifndef __MINGW32__
	/*
	 *	Open a pipe for child/parent communication, if necessary.
	 */
	if (exec_wait) {
		if (input_fd) {
			if (pipe(to_child) != 0) {
				RDEBUG("Couldn't open pipe to child: %s", fr_syserror(errno));
				return -1;
			}
		}
		if (output_fd) {
			if (pipe(from_child) != 0) {
				RDEBUG("Couldn't open pipe from child: %s", fr_syserror(errno));
				/* safe because these either need closing or are == -1 */
				close(to_child[0]);
				close(to_child[1]);
				return -1;
			}
		}
	}

	envp[0] = NULL;

	if (input_pairs) {
		vp_cursor_t cursor;
		char buffer[1024];

		/*
		 *	Set up the environment variables in the
		 *	parent, so we don't call libc functions that
		 *	hold mutexes.  They might be locked when we fork,
		 *	and will remain locked in the child.
		 */
		for (vp = fr_cursor_init(&cursor, &input_pairs); vp; vp = fr_cursor_next(&cursor)) {
			/*
			 *	Hmm... maybe we shouldn't pass the
			 *	user's password in an environment
			 *	variable...
			 */
			snprintf(buffer, sizeof(buffer), "%s=", vp->da->name);
			if (shell_escape) {
				for (p = buffer; *p != '='; p++) {
					if (*p == '-') {
						*p = '_';
					} else if (isalpha((int) *p)) {
						*p = toupper(*p);
					}
				}
//.........这里部分代码省略.........
开发者ID:amirdaly,项目名称:freeradius-server,代码行数:101,代码来源:exec.c


示例8: RDEBUG

// Create a new client session. This should really check the version number.
CSession2* CCentRepToolServer::NewSessionL(const TVersion&,const RMessage2&) const
	{
	RDEBUG("CentRepToolServer: CCentRepToolServer::NewSessionL");
	return new (ELeave) CCentRepToolSession();
	}
开发者ID:kuailexs,项目名称:symbiandump-mw3,代码行数:6,代码来源:CentRepToolServer.cpp


示例9: sql_xlat

/*
 *			SQL xlat function
 *
 *  For selects the first value of the first column will be returned,
 *  for inserts, updates and deletes the number of rows affected will be
 *  returned instead.
 */
static ssize_t sql_xlat(void *instance, REQUEST *request, char const *query, char *out, size_t freespace)
{
	rlm_sql_handle_t *handle = NULL;
	rlm_sql_row_t row;
	rlm_sql_t *inst = instance;
	ssize_t ret = 0;
	size_t len = 0;

	/*
	 *	Add SQL-User-Name attribute just in case it is needed
	 *	We could search the string fmt for SQL-User-Name to see if this is
	 * 	needed or not
	 */
	sql_set_user(inst, request, NULL);

	handle = fr_connection_get(inst->pool);
	if (!handle) {
		return 0;
	}

	rlm_sql_query_log(inst, request, NULL, query);

	/*
	 *	If the query starts with any of the following prefixes,
	 *	then return the number of rows affected
	 */
	if ((strncasecmp(query, "insert", 6) == 0) ||
	    (strncasecmp(query, "update", 6) == 0) ||
	    (strncasecmp(query, "delete", 6) == 0)) {
		int numaffected;
		char buffer[21]; /* 64bit max is 20 decimal chars + null byte */

		if (rlm_sql_query(&handle, inst, query) != RLM_SQL_OK) {
			char const *error = (inst->module->sql_error)(handle, inst->config);
			REDEBUG("SQL query failed: %s", error);

			ret = -1;
			goto finish;
		}

		numaffected = (inst->module->sql_affected_rows)(handle, inst->config);
		if (numaffected < 1) {
			RDEBUG("SQL query affected no rows");

			goto finish;
		}

		/*
		 *	Don't chop the returned number if freespace is
		 *	too small.  This hack is necessary because
		 *	some implementations of snprintf return the
		 *	size of the written data, and others return
		 *	the size of the data they *would* have written
		 *	if the output buffer was large enough.
		 */
		snprintf(buffer, sizeof(buffer), "%d", numaffected);

		len = strlen(buffer);
		if (len >= freespace){
			RDEBUG("rlm_sql (%s): Can't write result, insufficient string space", inst->config->xlat_name);

			(inst->module->sql_finish_query)(handle, inst->config);

			ret = -1;
			goto finish;
		}

		memcpy(out, buffer, len + 1); /* we did bounds checking above */
		ret = len;

		(inst->module->sql_finish_query)(handle, inst->config);

		goto finish;
	} /* else it's a SELECT statement */

	if (rlm_sql_select_query(&handle, inst, query) != RLM_SQL_OK) {
		ret = -1;  /* error handled by rlm_sql_select_query */

		goto finish;
	}

	ret = rlm_sql_fetch_row(&row, &handle, inst);
	if (ret) {
		REDEBUG("SQL query failed");
		(inst->module->sql_finish_select_query)(handle, inst->config);
		ret = -1;

		goto finish;
	}

	if (!row) {
		RDEBUG("SQL query returned no results");
		(inst->module->sql_finish_select_query)(handle, inst->config);
//.........这里部分代码省略.........
开发者ID:ridhoadilla,项目名称:freeradius-server,代码行数:101,代码来源:rlm_sql.c


示例10: CC_HINT


//.........这里部分代码省略.........
	 *	them, unless told to rely on count query only.
	 */
	if (!inst->config->simul_verify_query) {
		rcode = RLM_MODULE_OK;

		goto finish;
	}

	if (radius_axlat(&expanded, request, inst->config->simul_verify_query, sql_escape_func, inst) < 0) {
		rcode = RLM_MODULE_FAIL;

		goto finish;
	}

	if (rlm_sql_select_query(&handle, inst, expanded) != RLM_SQL_OK) goto finish;

	/*
	 *      Setup some stuff, like for MPP detection.
	 */
	request->simul_count = 0;

	if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL) {
		ipno = vp->vp_ipaddr;
	}

	if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL) {
		call_num = vp->vp_strvalue;
	}

	while (rlm_sql_fetch_row(&row, &handle, inst) == 0) {
		if (!row) break;

		if (!row[2]){
			RDEBUG("Cannot zap stale entry. No username present in entry");
			rcode = RLM_MODULE_FAIL;

			goto finish;
		}

		if (!row[1]){
			RDEBUG("Cannot zap stale entry. No session id in entry");
			rcode = RLM_MODULE_FAIL;

			goto finish;
		}

		if (row[3]) {
			nas_addr = inet_addr(row[3]);
		}

		if (row[4]) {
			nas_port = atoi(row[4]);
		}

		check = rad_check_ts(nas_addr, nas_port, row[2], row[1]);
		if (check == 0) {
			/*
			 *	Stale record - zap it.
			 */
			if (inst->config->deletestalesessions == true) {
				uint32_t framed_addr = 0;
				char proto = 0;
				int sess_time = 0;

				if (row[5])
					framed_addr = inet_addr(row[5]);
开发者ID:ridhoadilla,项目名称:freeradius-server,代码行数:67,代码来源:rlm_sql.c


示例11: acct_redundant

/*
 *	Generic function for failing between a bunch of queries.
 *
 *	Uses the same principle as rlm_linelog, expanding the 'reference' config
 *	item using xlat to figure out what query it should execute.
 *
 *	If the reference matches multiple config items, and a query fails or
 *	doesn't update any rows, the next matching config item is used.
 *
 */
static int acct_redundant(rlm_sql_t *inst, REQUEST *request, sql_acct_section_t *section)
{
	rlm_rcode_t		rcode = RLM_MODULE_OK;

	rlm_sql_handle_t	*handle = NULL;
	int			sql_ret;
	int			numaffected = 0;

	CONF_ITEM		*item;
	CONF_PAIR 		*pair;
	char const		*attr = NULL;
	char const		*value;

	char			path[MAX_STRING_LEN];
	char			*p = path;
	char			*expanded = NULL;

	rad_assert(section);

	if (section->reference[0] != '.') {
		*p++ = '.';
	}

	if (radius_xlat(p, sizeof(path) - (p - path), request, section->reference, NULL, NULL) < 0) {
		rcode = RLM_MODULE_FAIL;

		goto finish;
	}

	item = cf_reference_item(NULL, section->cs, path);
	if (!item) {
		rcode = RLM_MODULE_FAIL;

		goto finish;
	}

	if (cf_item_is_section(item)){
		REDEBUG("Sections are not supported as references");
		rcode = RLM_MODULE_FAIL;

		goto finish;
	}

	pair = cf_itemtopair(item);
	attr = cf_pair_attr(pair);

	RDEBUG2("Using query template '%s'", attr);

	handle = fr_connection_get(inst->pool);
	if (!handle) {
		rcode = RLM_MODULE_FAIL;

		goto finish;
	}

	sql_set_user(inst, request, NULL);

	while (true) {
		value = cf_pair_value(pair);
		if (!value) {
			RDEBUG("Ignoring null query");
			rcode = RLM_MODULE_NOOP;

			goto finish;
		}

		if (radius_axlat(&expanded, request, value, sql_escape_func, inst) < 0) {
			rcode = RLM_MODULE_FAIL;

			goto finish;
		}

		if (!*expanded) {
			RDEBUG("Ignoring null query");
			rcode = RLM_MODULE_NOOP;
			talloc_free(expanded);

			goto finish;
		}

		rlm_sql_query_log(inst, request, section, expanded);

		/*
		 *  If rlm_sql_query cannot use the socket it'll try and
		 *  reconnect. Reconnecting will automatically release
		 *  the current socket, and try to select a new one.
		 *
		 *  If we get RLM_SQL_RECONNECT it means all connections in the pool
		 *  were exhausted, and we couldn't create a new connection,
		 *  so we do not need to call fr_connection_release.
//.........这里部分代码省略.........
开发者ID:ridhoadilla,项目名称:freeradius-server,代码行数:101,代码来源:rlm_sql.c


示例12: eap_pwd_authenticate

static int
eap_pwd_authenticate (void *arg, EAP_HANDLER *handler)
{
    pwd_session_t *pwd_session;
    pwd_hdr *hdr;
    pwd_id_packet *id;
    EAP_PACKET *response;
    REQUEST *request, *fake;
    VALUE_PAIR *pw, **outvps, *vp;
    EAP_DS *eap_ds;
    int len, ret = 0;
    eap_pwd_t *inst = (eap_pwd_t *)arg;
    uint16_t offset;
    uint8_t exch, *buf, *ptr, msk[MSK_EMSK_LEN], emsk[MSK_EMSK_LEN];
    uint8_t peer_confirm[SHA256_DIGEST_LENGTH];
    BIGNUM *x = NULL, *y = NULL;

    if ((handler == NULL) ||
            ((eap_ds = handler->eap_ds) == NULL) ||
            (inst == NULL)) {
        return 0;
    }
    pwd_session = (pwd_session_t *)handler->opaque;
    request = handler->request;
    response = handler->eap_ds->response;
    hdr = (pwd_hdr *)response->type.data;

    buf = hdr->data;
    len = response->type.length - sizeof(pwd_hdr);

    /*
     * see if we're fragmenting, if so continue until we're done
     */
    if (pwd_session->out_buf_pos) {
        if (len) {
            RDEBUG2("pwd got something more than an ACK for a fragment");
        }
        return send_pwd_request(pwd_session, eap_ds);
    }

    /*
     * the first fragment will have a total length, make a
     * buffer to hold all the fragments
     */
    if (EAP_PWD_GET_LENGTH_BIT(hdr)) {
        if (pwd_session->in_buf) {
            RDEBUG2("pwd already alloced buffer for fragments");
            return 0;
        }
        pwd_session->in_buf_len = ntohs(buf[0] * 256 | buf[1]);
        if ((pwd_session->in_buf = malloc(pwd_session->in_buf_len)) == NULL) {
            RDEBUG2("pwd cannot malloc %d buffer to hold fragments",
                    pwd_session->in_buf_len);
            return 0;
        }
        memset(pwd_session->in_buf, 0, pwd_session->in_buf_len);
        pwd_session->in_buf_pos = 0;
        buf += sizeof(uint16_t);
        len -= sizeof(uint16_t);
    }

    /*
     * all fragments, including the 1st will have the M(ore) bit set,
     * buffer those fragments!
     */
    if (EAP_PWD_GET_MORE_BIT(hdr)) {
        rad_assert(pwd_session->in_buf != NULL);
        if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
            RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
            return 0;
        }
        memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
        pwd_session->in_buf_pos += len;

        /*
         * send back an ACK for this fragment
         */
        exch = EAP_PWD_GET_EXCHANGE(hdr);
        eap_ds->request->code = PW_EAP_REQUEST;
        eap_ds->request->type.type = PW_EAP_PWD;
        eap_ds->request->type.length = sizeof(pwd_hdr);
        if ((eap_ds->request->type.data = malloc(sizeof(pwd_hdr))) == NULL) {
            radlog(L_ERR, "rlm_eap_pwd: fragment ACK, out of memory");
            return 0;
        }
        hdr = (pwd_hdr *)eap_ds->request->type.data;
        EAP_PWD_SET_EXCHANGE(hdr, exch);
        return 1;

    }

    if (pwd_session->in_buf) {
        /*
         * the last fragment...
         */
        if ((pwd_session->in_buf_pos + len) > pwd_session->in_buf_len) {
            RDEBUG2("pwd will not overflow a fragment buffer. Nope, not prudent.");
            return 0;
        }
        memcpy(pwd_session->in_buf + pwd_session->in_buf_pos, buf, len);
//.........这里部分代码省略.........
开发者ID:ellors,项目名称:freeradius-server,代码行数:101,代码来源:rlm_eap_pwd.c


示例13: redisn_xlat

/*
 *	redisn xlat function. Right now only xGET are supported. Only
 *	the first element of the SELECT result will be used.
 */
static int redisn_xlat(void *instance, REQUEST *request,
		    char *fmt, char *out, size_t freespace,
		    UNUSED RADIUS_ESCAPE_STRING func)
{
	REDISSOCK *redis_socket=NULL;
	REDIS_ROW row;
	REDIS_INST *inst = instance;
	char querystr[MAX_QUERY_LEN];
	char redisnusername[MAX_STRING_LEN];
	size_t ret = 0;

	RDEBUG("redisn_xlat");

	/*
         * Add REDISN-User-Name attribute just in case it is needed
         *  We could search the string fmt for REDISN-User-Name to see if this is
         *  needed or not
         */
	redisn_set_user(inst, request, redisnusername, NULL);
	/*
	 * Do an xlat on the provided string (nice recursive operation).
	 */
	if (!radius_xlat(querystr, sizeof(querystr), fmt, request, redisn_escape_func, inst)) {
		radlog(L_ERR, "rlm_redisn (%s): xlat failed.",
		       inst->xlat_name);
		return 0;
	}

	query_log(request, inst, querystr);
	redis_socket = redisn_get_socket(inst);
	if (redis_socket == NULL)
		return 0;

	if (rlm_redisn_query(inst, redis_socket, querystr)<0) {
	  radlog(L_ERR, "rlm_redisn (%s): database query error, %s",
		 inst->xlat_name,querystr);
	  redisn_release_socket(inst,redis_socket);
	  return 0;
	  }

	ret = rlm_redisn_fetch_row(inst, redis_socket);

	if (ret) {
		RDEBUG("REDIS query did not succeed");
		(inst->redisn_finish_query)(inst, redis_socket);
		redisn_release_socket(inst,redis_socket);
		return 0;
	}

	row = redis_socket->row;
	if (row == NULL) {
		RDEBUG("REDIS query did not return any results");
		(inst->redisn_finish_query)(inst, redis_socket);
		redisn_release_socket(inst,redis_socket);
		return 0;
	}

	if (row[0] == NULL){
		RDEBUG("row[0] returned NULL");
		(inst->redisn_finish_query)(inst, redis_socket);
		redisn_release_socket(inst,redis_socket);
		return 0;
	}
	ret = strlen(row[0]);
	if (ret >= freespace){
		RDEBUG("Insufficient string space");
		(inst->redisn_finish_query)(inst, redis_socket);
		redisn_release_socket(inst,redis_socket);
		return 0;
	}

	strlcpy(out,row[0],freespace);

	RDEBUG("redisn_xlat finished");

	(inst->redisn_finish_query)(inst,redis_socket);
	redisn_release_socket(inst,redis_socket);
	return ret;
}
开发者ID:mguesdon,项目名称:freeradius-server,代码行数:83,代码来源:rlm_redisn.c


示例14: rlm_redisn_checksimul


//.........这里部分代码省略.........
	 *	them, unless told to rely on count query only.
	 */
	if (!inst->simul_verify_query ||
	    (inst->simul_verify_query[0] == '\0')) {
		redisn_release_socket(inst, redis_socket);
		return RLM_MODULE_OK;
	}

	radius_xlat(querystr, sizeof(querystr), inst->simul_verify_query, request, redisn_escape_func, inst);
	if(rlm_redisn_query(inst, redis_socket, querystr)) {
		radlog_request(L_ERR, 0, request, "Database query error");
		redisn_release_socket(inst, redis_socket);
		return RLM_MODULE_FAIL;
	}

        /*
         *      Setup some stuff, like for MPP detection.
         */
	request->simul_count = 0;

        if ((vp = pairfind(request->packet->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY)) != NULL)
                ipno = vp->vp_ipaddr;
        if ((vp = pairfind(request->packet->vps, PW_CALLING_STATION_ID, 0, TAG_ANY)) != NULL)
                call_num = vp->vp_strvalue;


	while (rlm_redisn_fetch_row(inst, redis_socket) == 0) {
		row = redis_socket->row;
		if (row == NULL)
			break;
		if (!row[2]){
			(inst->redisn_finish_query)(inst, redis_socket);
			redisn_release_socket(inst, redis_socket);
			RDEBUG("Cannot zap stale entry. No username present in entry.", inst->xlat_name);
			return RLM_MODULE_FAIL;
		}
		if (!row[1]){
			(inst->redisn_finish_query)(inst, redis_socket);
			redisn_release_socket(inst, redis_socket);
			RDEBUG("Cannot zap stale entry. No session id in entry.", inst->xlat_name);
			return RLM_MODULE_FAIL;
		}
		if (row[3])
			nas_addr = inet_addr(row[3]);
		if (row[4])
			nas_port = atoi(row[4]);

		check = rad_check_ts(nas_addr, nas_port, row[2], row[1]);

		if (check == 0) {
			/*
			 *	Stale record - zap it.
			 */
			if (inst->deletestalesessions == TRUE) {
				uint32_t framed_addr = 0;
				char proto = 0;
				int sess_time = 0;

				if (row[5])
					framed_addr = inet_addr(row[5]);
				if (row[7]){
					if (strcmp(row[7], "PPP") == 0)
						proto = 'P';
					else if (strcmp(row[7], "SLIP") == 0)
						proto = 'S';
				}
开发者ID:mguesdon,项目名称:freeradius-server,代码行数:67,代码来源:rlm_redisn.c


示例15: radius_readfrom_program

/** Read from the child process.
 *
 * @param request The current request.
 * @param fd file descriptor to read from.
 * @param pid pid of child, will be reaped if it dies.
 * @param timeout amount of time to wait, in seconds.
 * @param answer buffer to write into.
 * @param left length of buffer.
 * @return -1 on error, or length of output.
 */
int radius_readfrom_program(REQUEST *request, int fd, pid_t pid, int timeout,
			    char *answer, int left)
{
	int done = 0;
#ifndef __MINGW32__
	int status;
	struct timeval start;
#ifdef O_NONBLOCK
	bool nonblock = true;
#endif

#ifdef O_NONBLOCK
	/*
	 *	Try to set it non-blocking.
	 */
	do {
		int flags;

		if ((flags = fcntl(fd, F_GETFL, NULL)) < 0)  {
			nonblock = false;
			break;
		}

		flags |= O_NONBLOCK;
		if( fcntl(fd, F_SETFL, flags) < 0) {
			nonblock = false;
			break;
		}
	} while (0);
#endif


	/*
	 *	Read from the pipe until we doesn't get any more or
	 *	until the message is full.
	 */
	gettimeofday(&start, NULL);
	while (1) {
		int rcode;
		fd_set fds;
		struct timeval when, elapsed, wake;

		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		gettimeofday(&when, NULL);
		tv_sub(&when, &start, &elapsed);
		if (elapsed.tv_sec >= timeout) goto too_long;

		when.tv_sec = timeout;
		when.tv_usec = 0;
		tv_sub(&when, &elapsed, &wake);

		rcode = select(fd + 1, &fds, NULL, NULL, &wake);
		if (rcode == 0) {
		too_long:
			RDEBUG("Child PID %u is taking too much time: forcing failure and killing child.", pid);
			kill(pid, SIGTERM);
			close(fd); /* should give SIGPIPE to child, too */

			/*
			 *	Clean up the child entry.
			 */
			rad_waitpid(pid, &status);
			return -1;
		}
		if (rcode < 0) {
			if (errno == EINTR) continue;
			break;
		}

#ifdef O_NONBLOCK
		/*
		 *	Read as many bytes as possible.  The kernel
		 *	will return the number of bytes available.
		 */
		if (nonblock) {
			status = read(fd, answer + done, left);
		} else
#endif
			/*
			 *	There's at least 1 byte ready: read it.
			 */
			status = read(fd, answer + done, 1);

		/*
		 *	Nothing more to read: stop.
		 */
		if (status == 0) {
			break;
//.........这里部分代码省略.........
开发者ID:amirdaly,项目名称:freeradius-server,代码行数:101,代码来源:exec.c


示例16: switch

void CCentRepToolSession::DispatchMessageL(const RMessage2& aMessage)
	{
	//Subsession management
	switch (aMessage.Function())
	{
		case ECreateRepositorySubSession:
		case ECreateCheckAccessSession:
		{
			RDEBUG("CentRepTool: New repository session");
			NewRepositorySessionL( aMessage);
			return;
		}
		case ECloseRepositorySubSession:
		case ECloseCheckAcceessSession:
		{
			RDEBUG("CentRepTool: Close repository session");
			DeleteRepositorySession( aMessage);
			return;
		}
		case ECheckCommitState :
		{
			RDEBUG("CentRepTool: Check last commit state");
			CRepositorySession::CheckCommitStateL();
			return;
		}
		case EPerformCentRepToolRFS :
		{
			RDEBUG("CentRepTool: Perform RFS");
			PerformRFSL();
			return;
		}
	}

	//Trusted session operations
	CRepositorySession * repositorySession = RepositorySessionFromHandle( aMessage);
	iCurrentSession = repositorySession;
			
	switch (aMessage.Function())
	{
		case EInitRepositorySession:
		{
			RDEBUG("CentRepTool: Init repository session");
			repositorySession->InitRepositorySessionL();
		}
		break;
		case ESetSIDWRForSetting :
		{
			RDEBUG("CentRepTool: Add SID for individual setting");
			repositorySession->SetSecurityIdForSettingL( aMessage);
		}
		break;
		case ESetSIDWRForRange:
		{
			RDEBUG("CentRepTool: Add SID for range");
			repositorySession->SetSecurityIdForRangeL( aMessage);
		}
		break;		
		case ERestoreSetting :
		{
			RDEBUG("CentRepTool: Restore individual setting");
			repositorySession->RestoreSettingL( aMessage);
		}
		break;		
		case ERestoreRange :
		{
			RDEBUG("CentRepTool: Restore range");
			repositorySession->RestoreRangeL( aMessage);
		}
		break;
		case EAddSIDWRForDefaults :
		{
			RDEBUG("CentRepTool: Add SID for all settings (default, range, mask)");
			repositorySession->AddSidForDefaultsL( aMessage);
		}
		break;
		case ERestoreDefaults :
		{
			RDEBUG("CentRepTool: ");
			RDEBUG("CentRepTool: Remove SID from all settings (default, range, mask)");
			repositorySession->RestoreDefaultsL( aMessage);
		}
		break;
		case EFlushRepository :
		{
			RDEBUG("CentRepTool: Commit security changes in repository");
			repositorySession->CommitRepositoryL();
		}
		break;
		case ESetSIDWRForMask :
		{
			RDEBUG("CentRepTool: Set SID for mask setting");
			repositorySession->SetSecurityIdForMaskL( aMessage);
		}
		break;
		case ERestoreMask :
		{
			RDEBUG("CentRepTool: Restore mask setting");
			repositorySession->RestoreMaskL( aMessage);
		}
		break;
//.........这里部分代码省略.........
开发者ID:kuailexs,项目名称:symbiandump-mw3,代码行数:101,代码来源:CentRepToolServer.cpp


示例17: dhcp_process

static int dhcp_process(REQUEST *request)
{
	int rcode;
	unsigned int i;
	VALUE_PAIR *vp;
	dhcp_socket_t *sock;

	vp = pairfind(request->packet->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */
	if (vp) {
		DICT_VALUE *dv = dict_valbyattr(DHCP2ATTR(53), vp->vp_integer);
		DEBUG("Trying sub-section dhcp %s {...}",
		      dv->name ? dv->name : "<unknown>");
		rcode = module_post_auth(vp->vp_integer, request);
	} else {
		DEBUG("DHCP: Failed to find DHCP-Message-Type in packet!");
		rcode = RLM_MODULE_FAIL;
	}

	vp = pairfind(request->reply->vps, DHCP2ATTR(53)); /* DHCP-Message-Type */
	if (vp) {
		request->reply->code = vp->vp_integer;
		if ((request->reply->code != 0) &&
		    (request->reply->code < PW_DHCP_OFFSET)) {
			request->reply->code += PW_DHCP_OFFSET;
		}
	}
	else switch (rcode) {
	case RLM_MODULE_OK:
	case RLM_MODULE_UPDATED:
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = PW_DHCP_OFFER;
			break;

		} else if (request->packet->code == PW_DHCP_REQUEST) {
			request->reply->code = PW_DHCP_ACK;
			break;
		}
		request->reply->code = PW_DHCP_NAK;
		break;

	default:
	case RLM_MODULE_REJECT:
	case RLM_MODULE_FAIL:
	case RLM_MODULE_INVALID:
	case RLM_MODULE_NOOP:
	case RLM_MODULE_NOTFOUND:
		if (request->packet->code == PW_DHCP_DISCOVER) {
			request->reply->code = 0; /* ignore the packet */
		} else {
			request->reply->code = PW_DHCP_NAK;
		}
		break;

	case RLM_MODULE_HANDLED:
		request->reply->code = 0; /* ignore the packet */
		break;
	}

	/*
	 *	TODO: Handle 'output' of RLM_MODULE when acting as a
	 *	DHCP relay We may  

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C++ RDEBUG2函数代码示例发布时间:2022-05-30
下一篇:
C++ RDCWARN函数代码示例发布时间:2022-05-30
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap