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

📄 options.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    /* Do we add a NUL? */	    if (terminate && dhcp_options [code].format [0] == 't') {		    length++;		    tto = 1;	    } else {		    tto = 0;	    }	    /* Try to store the option. */	    	    /* If the option's length is more than 255, we must store it	       in multiple hunks.   Store 255-byte hunks first.  However,	       in any case, if the option data will cross a buffer	       boundary, split it across that boundary. */	    ix = 0;	    optstart = bufix;	    while (length) {		    unsigned char incr = length > 255 ? 255 : length;		    int consumed = 0;		    		    /* If this hunk of the buffer will cross a		       boundary, only go up to the boundary in this		       pass. */		    if (bufix < first_cutoff &&			bufix + incr > first_cutoff)			    incr = first_cutoff - bufix;		    else if (bufix < second_cutoff &&			     bufix + incr > second_cutoff)			    incr = second_cutoff - bufix;		    		    /* If this option is going to overflow the buffer,		       skip it. */		    if (bufix + 2 + incr > buflen) {			    bufix = optstart;			    break;		    }		    		    /* Everything looks good - copy it in! */		    buffer [bufix] = code;		    buffer [bufix + 1] = incr;		    if (tto && incr == length) {			    memcpy (buffer + bufix + 2,				    od.data + ix, (unsigned)(incr - 1));			    buffer [bufix + 2 + incr - 1] = 0;		    } else {			    memcpy (buffer + bufix + 2,				    od.data + ix, (unsigned)incr);		    }		    length -= incr;		    ix += incr;		    bufix += 2 + incr;	    }	    data_string_forget (&od, MDL);	}	return bufix;}/* Format the specified option so that a human can easily read it. */const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)	struct option *option;	const unsigned char *data;	unsigned len;	int emit_commas;	int emit_quotes;{	static char optbuf [32768]; /* XXX */	int hunksize = 0;	int opthunk = 0;	int hunkinc = 0;	int numhunk = -1;	int numelem = 0;	char fmtbuf [32];	struct enumeration *enumbuf [32];	int i, j, k, l;	char *op = optbuf;	const unsigned char *dp = data;	struct in_addr foo;	char comma;	unsigned long tval;	if (emit_commas)		comma = ',';	else		comma = ' ';		memset (enumbuf, 0, sizeof enumbuf);	/* Figure out the size of the data. */	for (l = i = 0; option -> format [i]; i++, l++) {		if (!numhunk) {			log_error ("%s: Extra codes in format string: %s",				   option -> name,				   &(option -> format [i]));			break;		}		numelem++;		fmtbuf [l] = option -> format [i];		switch (option -> format [i]) {		      case 'a':			--numelem;			fmtbuf [l] = 0;			numhunk = 0;			break;		      case 'A':			--numelem;			fmtbuf [l] = 0;			numhunk = 0;			break;		      case 'E':			/* Skip the universe name. */			while (option -> format [i] &&			       option -> format [i] != '.')				i++;		      case 'X':			for (k = 0; k < len; k++) {				if (!isascii (data [k]) ||				    !isprint (data [k]))					break;			}			/* If we found no bogus characters, or the bogus			   character we found is a trailing NUL, it's			   okay to print this option as text. */			if (k == len || (k + 1 == len && data [k] == 0)) {				fmtbuf [l] = 't';				numhunk = -2;			} else {				fmtbuf [l] = 'x';				hunksize++;				comma = ':';				numhunk = 0;			}			fmtbuf [l + 1] = 0;			break;		      case 'd':		      case 't':			fmtbuf [l] = 't';			fmtbuf [l + 1] = 0;			numhunk = -2;			break;		      case 'N':			k = i;			while (option -> format [i] &&			       option -> format [i] != '.')				i++;			enumbuf [l] =				find_enumeration (&option -> format [k] + 1,						  i - k - 1);			hunksize += 1;			hunkinc = 1;			break;		      case 'I':		      case 'l':		      case 'L':		      case 'T':			hunksize += 4;			hunkinc = 4;			break;		      case 's':		      case 'S':			hunksize += 2;			hunkinc = 2;			break;		      case 'b':		      case 'B':		      case 'f':			hunksize++;			hunkinc = 1;			break;		      case 'e':			break;		      case 'o':			opthunk += hunkinc;			break;		      default:			log_error ("%s: garbage in format string: %s",			      option -> name,			      &(option -> format [i]));			break;		} 	}	/* Check for too few bytes... */	if (hunksize - opthunk > len) {		log_error ("%s: expecting at least %d bytes; got %d",		      option -> name,		      hunksize, len);		return "<error>";	}	/* Check for too many bytes... */	if (numhunk == -1 && hunksize < len)		log_error ("%s: %d extra bytes",		      option -> name,		      len - hunksize);	/* If this is an array, compute its size. */	if (!numhunk)		numhunk = len / hunksize;	/* See if we got an exact number of hunks. */	if (numhunk > 0 && numhunk * hunksize < len)		log_error ("%s: %d extra bytes at end of array\n",		      option -> name,		      len - numhunk * hunksize);	/* A one-hunk array prints the same as a single hunk. */	if (numhunk < 0)		numhunk = 1;	/* Cycle through the array (or hunk) printing the data. */	for (i = 0; i < numhunk; i++) {		for (j = 0; j < numelem; j++) {			switch (fmtbuf [j]) {			      case 't':				if (emit_quotes)					*op++ = '"';				for (; dp < data + len; dp++) {					if (!isascii (*dp) ||					    !isprint (*dp)) {						/* Skip trailing NUL. */					    if (dp + 1 != data + len ||						*dp != 0) {						    sprintf (op, "\\%03o",							     *dp);						    op += 4;					    }					} else if (*dp == '"' ||						   *dp == '\'' ||						   *dp == '$' ||						   *dp == '`' ||						   *dp == '\\') {						*op++ = '\\';						*op++ = *dp;					} else						*op++ = *dp;				}				if (emit_quotes)					*op++ = '"';				*op = 0;				break;				/* pretty-printing an array of enums is				   going to get ugly. */			      case 'N':				if (!enumbuf [j])					goto enum_as_num;				for (i = 0; ;i++) {					if (!enumbuf [j] -> values [i].name)						goto enum_as_num;					if (enumbuf [j] -> values [i].value ==					    *dp)						break;				}				strcpy (op, enumbuf [j] -> values [i].name);				op += strlen (op);				break;			      case 'I':				foo.s_addr = htonl (getULong (dp));				strcpy (op, inet_ntoa (foo));				dp += 4;				break;			      case 'l':				sprintf (op, "%ld", (long)getLong (dp));				dp += 4;				break;			      case 'T':				tval = getULong (dp);				if (tval == -1)					sprintf (op, "%s", "infinite");				else					sprintf (op, "%ld", tval);				break;			      case 'L':				sprintf (op, "%ld",					 (unsigned long)getULong (dp));				dp += 4;				break;			      case 's':				sprintf (op, "%d", (int)getShort (dp));				dp += 2;				break;			      case 'S':				sprintf (op, "%d", (unsigned)getUShort (dp));				dp += 2;				break;			      case 'b':				sprintf (op, "%d", *(const char *)dp++);				break;			      case 'B':			      enum_as_num:				sprintf (op, "%d", *dp++);				break;			      case 'x':				sprintf (op, "%x", *dp++);				break;			      case 'f':				strcpy (op, *dp++ ? "true" : "false");				break;			      default:				log_error ("Unexpected format code %c",					   fmtbuf [j]);			}			op += strlen (op);			if (dp == data + len)				break;			if (j + 1 < numelem && comma != ':')				*op++ = ' ';		}		if (i + 1 < numhunk) {			*op++ = comma;		}		if (dp == data + len)			break;	}	return optbuf;}int get_option (result, universe, packet, lease, client_state,		in_options, cfg_options, options, scope, code, file, line)	struct data_string *result;	struct universe *universe;	struct packet *packet;	struct lease *lease;	struct client_state *client_state;	struct option_state *in_options;	struct option_state *cfg_options;	struct option_state *options;	struct binding_scope **scope;	unsigned code;	const char *file;	int line;{	struct option_cache *oc;	if (!universe -> lookup_func)		return 0;	oc = ((*universe -> lookup_func) (universe, options, code));	if (!oc)		return 0;	if (!evaluate_option_cache (result, packet, lease, client_state,				    in_options, cfg_options, scope, oc,				    file, line))		return 0;	return 1;}void set_option (universe, options, option, op)	struct universe *universe;	struct option_state *options;	struct option_cache *option;	enum statement_op op;{	struct option_cache *oc, *noc;	switch (op) {	      case if_statement:	      case add_statement:	      case eval_statement:	      case break_statement:	      default:		log_error ("bogus statement type in do_option_set.");		break;	      case default_option_statement:		oc = lookup_option (universe, options,				    option -> option -> code);		if (oc)			break;		save_option (universe, options, option);		break;	      case supersede_option_statement:	      case send_option_statement:		/* Install the option, replacing any existing version. */		save_option (universe, options, option);		break;	      case append_option_statement:	      case prepend_option_statement:		oc = lookup_option (universe, options,				    option -> option -> code);		if (!oc) {			save_option (universe, options, option);			break;		}		/* If it's not an expression, make it into one. */		if (!oc -> expression && oc -> data.len) {			if (!expression_allocate (&oc -> expression, MDL)) {				log_error ("Can't allocate const expression.");				break;			}			oc -> expression -> op = expr_const_data;			data_string_copy				(&oc -> expression -> data.const_data,				 &oc -> data, MDL);			data_string_forget (&oc -> data, MDL);		}		noc = (struct option_cache *)0;		if (!option_cache_allocate (&noc, MDL))			break;		if (op == append_option_statement) {			if (!make_concat (&noc -> expression,					  oc -> expression,					  option -> expression)) {				option_cache_dereference (&noc, MDL);				break;			}		} else {			if (!make_concat (&noc -> expression,					  option -> expression,					  oc -> expression)) {				option_cache_dereference (&noc, MDL);				break;			}		}		noc -> option = oc -> option;		save_option (universe, options, noc);		option_cache_dereference (&noc, MDL);		break;	}}struct option_cache *lookup_option (universe, options, code)	struct universe *universe;	struct option_state *options;	unsigned code;{	if (!options)		return (struct option_cache *)0;	if (universe -> lookup_func)		return (*universe -> lookup_func) (universe, options, code);	else		log_error ("can't look up options in %s space.",			   universe -> name);	return (struct option_cache *)0;}struct option_cache *lookup_hashed_option (universe, options, code)	struct universe *universe;	struct option_state *options;	unsigned code;{	int hashix;	pair bptr;	pair *hash;	/* Make sure there's a hash table. */	if (universe -> index >= options -> universe_count ||	    !(options -> universes [universe -> index]))

⌨️ 快捷键说明

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