📄 dhcp-client-cache.c
字号:
/* $Header: /cvsroot/dhcp-agent/dhcp-agent/src/dhcp-client-cache.c,v 1.17 2003/07/06 05:34:33 actmodern Exp $ * * Copyright 2002 Thamer Alharbash <tmh@whitefang.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. The names of the authors may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * Client cache object: * * We use this to load cached DHCP options, and save them. * */#define MODULE_NAME "dhcp-client-cache"#include "dhcp-local.h"#include "dhcp-limits.h"#include "dhcp-libutil.h"#include "dhcp-librawnet.h"#include "dhcp-option.h"#include "dhcp-cache-entry.h"#include "dhcp-client-cache.h"#include "dhcp-options-strings.h"/* * * * * * * * * * * * * * * * * * * Destroy/Create/Purge routines. * * * * * * * * * * * * * * * * * * *//* constructor. */client_cache_t *client_cache_create(const char *interface){ client_cache_t *cc; cc = xmalloc(sizeof(client_cache_t)); cc->interface = interface; /* don't copy just point. */ cc->vars = list_create(); return cc;}/* FIXME: make it use destroy_list. *//* purges list in cache object. */void client_cache_purge(client_cache_t *cc){ cache_entry_purge_list(cc->vars); cc->vars = list_create(); return;}/* destructor. */void client_cache_destroy(client_cache_t *cc){ if(cc->vars) client_cache_purge(cc); xfree(cc); return;}/* * * * * * * * * * * * * * * * Cache Filename Routines. * * * * * * * * * * * * * * * */static char *get_fname_proc(const client_cache_t *cc, const char *suffix){ char *fname; stringbuffer_t *sb; sb = stringbuffer_create(); stringbuffer_aprintf(sb, "%s.%s", cc->interface, suffix); fname = xstrdup(stringbuffer_getstring(sb)); /* FIXME: use a stringbuffer associated creation routine. */ stringbuffer_destroy(sb); return fname;}static char *get_fname(const client_cache_t *cc){ return (get_fname_proc(cc, "cache"));}static char *get_fname_tmp(client_cache_t *cc){ return (get_fname_proc(cc, "cache.tmp"));}/* * * * * * * * * * * * * Cache Manipulation * * * * * * * * * * * * *//* update cache: move temp cache over real cache. */void client_cache_update(client_cache_t *cc){ char *fname_tmp, *fname; fname_tmp = get_fname_tmp(cc); fname = get_fname(cc); file_move(fname_tmp, fname); xfree(fname); xfree(fname_tmp); return;}/* delete old temporary cache. */void client_cache_delete_tmp_cache(client_cache_t *cc){ char *fname = get_fname_tmp(cc); file_delete(fname); xfree(fname); return;}/* delete cache. */void client_cache_delete_cache(client_cache_t *cc){ char *fname = get_fname(cc); file_delete(fname); xfree(fname); return;}static int client_cache_is_empty_proc(client_cache_t *cc, int tmp){ int retval; char *fname; if(tmp) fname = get_fname_tmp(cc); else fname = get_fname(cc); if(file_exists(fname)) retval = 0; else retval = 1; xfree(fname); return retval;}/* check if cache is empty. */int client_cache_is_empty(client_cache_t *cc){ return client_cache_is_empty_proc(cc, 0);}/* check if temporary cache is empty. */int client_cache_is_empty_tmp(client_cache_t *cc){ return client_cache_is_empty_proc(cc, 1);}/* check if a cache entry is for a timer option. */static int is_timer_option(cache_entry_t *ce){ if(ce->tag == TAG_DHCP_IP_ADDRESS_LEASE_TIME || ce->tag == TAG_DHCP_RENEWAL_TIME || ce->tag == TAG_DHCP_REBINDING_TIME) return 1; else return 0;}/* * * * * * * * * * * * Cache load/dump * * * * * * * * * * * *//* read next cache entry from file. */static cache_entry_t *read_next_cache_var(varfile_t *varfile){ cache_entry_t *cache_entry; int retval; retval = varfile_get_next_var(varfile); switch (retval) { case VARFILE_PARSE_ERROR: ERROR_MESSAGE("parser error in cache: %s : %d", varfile_get_filename(varfile), varfile_get_lineno(varfile)); return NULL; case VARFILE_EOF: return NULL; case VARFILE_SUCCESS: cache_entry = create_cache_entry(atoi(varfile_get_name(varfile)), varfile_get_name(varfile), varfile_get_val(varfile)); return cache_entry; default: FATAL_MESSAGE("client-cache: read_next_cache_var: internal error -- please report this."); } /* we never get here. */ return NULL;}/* Load up cache from file named by filename. */static int client_cache_load_proc(client_cache_t *cc, char *filename){ varfile_t *varfile; cache_entry_t *cache_entry; varfile = create_varfile(filename, VARFILE_VARVAL_MODE); if(varfile == NULL) { ERROR_MESSAGE("unable to create varfile"); return -1; } /* Read up any vars. */ while((cache_entry = read_next_cache_var(varfile)) != NULL) list_add(cc->vars, cache_entry); destroy_varfile(varfile); return 0;}/* load cache */static int client_cache_load(client_cache_t *cc, uint8_t use_tmp){ char *fname; int retval; client_cache_purge(cc); if(use_tmp) fname = get_fname_tmp(cc); else fname = get_fname(cc); retval = client_cache_load_proc(cc, fname); xfree(fname); return retval;}/* load cache and optionally run the check routine passed on it. */static list_t *client_cache_load_options_proc(client_cache_t *cc, uint8_t use_tmp, int (*check)(cache_entry_t *ce)){ list_t *option_list; cache_entry_t *ce; dhcp_opt_t *option; if(client_cache_load(cc, use_tmp)) return NULL; /* create the option list. */ option_list = list_create(); /* now convert from cache entry to dhcp option. */ list_rewind(cc->vars); while((ce = list_next(cc->vars)) != NULL) { /* check if we want it. */ if((check != NULL && check(ce)) || (check == NULL)) { option = dhcp_opt_create_from_host_string(ce->tag, ce->value); if(option == NULL) { ERROR_MESSAGE("could not convert option %s from cached value: %s", dhcp_option_printable_string_get(ce->tag), ce->value); FATAL_MESSAGE("cache is corrupt! exiting."); } list_add(option_list, option); } } return option_list;}/* dump options into file. here we take data and write it into * serialized form. we always do this to the temp file. the list * should contain pointers to dhcp_opt_t. */int client_cache_dump_options(client_cache_t *cc, list_t *options){ FILE *fp; char *name; char *val; dhcp_opt_t *opt; stringbuffer_t *sb; uint8_t tag; sb = stringbuffer_create(); name = get_fname_tmp(cc); fp = file_create_and_truncate_safe(name, "a"); xfree(name); if(fp == NULL) return -1; list_rewind(options); while((opt = list_next(options)) != NULL) { tag = dhcp_opt_get_tag(opt); val = dhcp_opt_get_internal_string(opt); stringbuffer_clear(sb); stringbuffer_append(sb, val); stringbuffer_replace(sb, "\\", "\\\\"); stringbuffer_replace(sb, "\"", "\\\""); fprintf(fp, "%"PRIu8"=\"%s\" # %s\n", tag, stringbuffer_getstring(sb), dhcp_option_printable_string_get(tag)); xfree(val); } stringbuffer_destroy(sb); fclose(fp); return 0;}list_t *client_cache_load_options(client_cache_t *cc, uint8_t use_tmp){ return client_cache_load_options_proc(cc, use_tmp, NULL);}list_t *client_cache_load_timer_options(client_cache_t *cc, uint8_t use_tmp){ return client_cache_load_options_proc(cc, use_tmp, is_timer_option);}void client_pretty_print_cache(client_cache_t *cc, uint8_t use_tmp){ dhcp_opt_t *option; cache_entry_t *ce; const char *name; char *val; list_t *options; if((options = client_cache_load_options_proc(cc, use_tmp, NULL)) == NULL) { FATAL_MESSAGE("could not load cached lease"); } INFO_MESSAGE("Lease contents:"); list_rewind(cc->vars); while((ce = list_next(cc->vars)) != NULL) { option = dhcp_opt_create_from_host_string(ce->tag, ce->value); name = dhcp_option_printable_string_get(dhcp_opt_get_tag(option)); val = dhcp_opt_get_internal_string(option); INFO_MESSAGE("%s : %s", name, val); xfree(val); } INFO_MESSAGE(" "); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -