Add enum alias name or change name

本文介绍了一种通过反射机制更改Java枚举名称的方法,使枚举的name()和toString()方法返回期望的名字,同时确保Enum.valueOf()方法的正常工作。此方法适用于需要将保留关键字用作枚举值的情况。

Question

Java enum’s name declare in source code, as some reason, we want to change its name to another one.

For Example

Have a enum:

enum modifier {
    _public, _private, _protected;
}   

As we know “public”, “private”,”protected” are java reserved keywords, add ‘_’ to head of them for enum names. But you want name(), toString() method return “public” and etc.

Resolution

We can change name, supporting Enum.valueOf(), by reflection.

enum modifier {
    _public, _private, _protected;

    static {
        try {
            Field efield = Enum.class.getDeclaredField("name");
            efield.setAccessible(true);
            efield.set(modifier._public, "public");
            efield.set(modifier._private, "private");
            efield.set(modifier._protected, "protected");
            Method dirMethod = Class.class.getDeclaredMethod("enumConstantDirectory");
            dirMethod.setAccessible(true);
            Map<String, modifier> cTypeMap = (Map<String, modifier>) dirMethod.invoke(modifier.class);
            cTypeMap.put("_public", modifier._public);
            cTypeMap.put("_private", modifier._private);
            cTypeMap.put("_protected", modifier._protected);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
    public static void main(String[] args) {
        System.out.println(Arrays.deepToString(modifier.values()));
        System.out.println(Enum.valueOf(modifier.class, "_public"));
        System.out.println(Enum.valueOf(modifier.class, "public"));
    }

We can see the following output:

[public, private, protected]
public
public

Enjoy it

解析这份patch改动内容,每处改动意味着什么 Index: b/include/linux/netdevice.h =================================================================== --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -936,6 +936,16 @@ enum flow_offload_type { FLOW_OFFLOAD_DEL, }; +struct netdev_name_node { + struct hlist_node hlist; + struct list_head list; + struct net_device *dev; + const char *name; +}; + +int netdev_name_node_alt_create(struct net_device *dev, const char *name); +int netdev_name_node_alt_destroy(struct net_device *dev, const char *name); + /* * This structure defines the management hooks for network devices. * The following hooks can be defined; unless noted otherwise, they are @@ -1625,7 +1635,7 @@ enum netdev_ml_priv_type { * (i.e. as seen by users in the "Space.c" file). It is the name * of the interface. * - * @name_hlist: Device name hash chain, please keep it close to name[] + * @name_node: Name hashlist node * @ifalias: SNMP alias * @mem_end: Shared memory end * @mem_start: Shared memory start @@ -1847,7 +1857,7 @@ enum netdev_ml_priv_type { struct net_device { char name[IFNAMSIZ]; - struct hlist_node name_hlist; + struct netdev_name_node *name_node; struct dev_ifalias __rcu *ifalias; /* * I/O specific fields Index: b/include/uapi/linux/if.h =================================================================== --- a/include/uapi/linux/if.h +++ b/include/uapi/linux/if.h @@ -33,6 +33,7 @@ #define IFNAMSIZ 16 #endif /* __UAPI_DEF_IF_IFNAMSIZ */ #define IFALIASZ 256 +#define ALTIFNAMSIZ 128 #include <linux/hdlc/ioctl.h> /* For glibc compatibility. An empty enum does not compile. */ Index: b/include/uapi/linux/if_link.h =================================================================== --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -167,6 +167,8 @@ enum { IFLA_NEW_IFINDEX, IFLA_MIN_MTU, IFLA_MAX_MTU, + IFLA_PROP_LIST, + IFLA_ALT_IFNAME, /* Alternative ifname */ __IFLA_MAX }; Index: b/include/uapi/linux/rtnetlink.h =================================================================== --- a/include/uapi/linux/rtnetlink.h +++ b/include/uapi/linux/rtnetlink.h @@ -165,6 +165,12 @@ enum { #define RTM_GETNEXTHOP RTM_GETNEXTHOP RTM_UPDATEAST = 107, #define RTM_UPDATEAST RTM_UPDATEAST + RTM_NEWLINKPROP = 108, +#define RTM_NEWLINKPROP RTM_NEWLINKPROP + RTM_DELLINKPROP, +#define RTM_DELLINKPROP RTM_DELLINKPROP + RTM_GETLINKPROP, +#define RTM_GETLINKPROP RTM_GETLINKPROP __RTM_MAX, #define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1) Index: b/net/core/dev.c =================================================================== --- a/net/core/dev.c +++ b/net/core/dev.c @@ -253,6 +253,122 @@ static inline void rps_unlock(struct sof #endif } +static struct netdev_name_node *netdev_name_node_alloc(struct net_device *dev, + const char *name) +{ + struct netdev_name_node *name_node; + + name_node = kmalloc(sizeof(*name_node), GFP_KERNEL); + if (!name_node) + return NULL; + INIT_HLIST_NODE(&name_node->hlist); + name_node->dev = dev; + name_node->name = name; + return name_node; +} + +static struct netdev_name_node * +netdev_name_node_head_alloc(struct net_device *dev) +{ + struct netdev_name_node *name_node; + + name_node = netdev_name_node_alloc(dev, dev->name); + if (!name_node) + return NULL; + INIT_LIST_HEAD(&name_node->list); + return name_node; +} + +static void netdev_name_node_free(struct netdev_name_node *name_node) +{ + kfree(name_node); +} + +static void netdev_name_node_add(struct net *net, + struct netdev_name_node *name_node) +{ + hlist_add_head_rcu(&name_node->hlist, + dev_name_hash(net, name_node->name)); +} + +static void netdev_name_node_del(struct netdev_name_node *name_node) +{ + hlist_del_rcu(&name_node->hlist); +} + +static struct netdev_name_node *netdev_name_node_lookup(struct net *net, + const char *name) +{ + struct hlist_head *head = dev_name_hash(net, name); + struct netdev_name_node *name_node; + + hlist_for_each_entry(name_node, head, hlist) + if (!strcmp(name_node->name, name)) + return name_node; + return NULL; +} + +static struct netdev_name_node *netdev_name_node_lookup_rcu(struct net *net, + const char *name) +{ + struct hlist_head *head = dev_name_hash(net, name); + struct netdev_name_node *name_node; + + hlist_for_each_entry_rcu(name_node, head, hlist) + if (!strcmp(name_node->name, name)) + return name_node; + return NULL; +} + +int netdev_name_node_alt_create(struct net_device *dev, const char *name) +{ + struct netdev_name_node *name_node; + struct net *net = dev_net(dev); + + name_node = netdev_name_node_lookup(net, name); + if (name_node) + return -EEXIST; + name_node = netdev_name_node_alloc(dev, name); + if (!name_node) + return -ENOMEM; + netdev_name_node_add(net, name_node); + /* The node that holds dev->name acts as a head of per-device list. */ + list_add_tail(&name_node->list, &dev->name_node->list); + + return 0; +} +EXPORT_SYMBOL(netdev_name_node_alt_create); + +static void __netdev_name_node_alt_destroy(struct netdev_name_node *name_node) +{ + list_del(&name_node->list); + netdev_name_node_del(name_node); + kfree(name_node->name); + netdev_name_node_free(name_node); +} + +int netdev_name_node_alt_destroy(struct net_device *dev, const char *name) +{ + struct netdev_name_node *name_node; + struct net *net = dev_net(dev); + + name_node = netdev_name_node_lookup(net, name); + if (!name_node) + return -ENOENT; + __netdev_name_node_alt_destroy(name_node); + + return 0; +} +EXPORT_SYMBOL(netdev_name_node_alt_destroy); + +static void netdev_name_node_alt_flush(struct net_device *dev) +{ + struct netdev_name_node *name_node, *tmp; + + list_for_each_entry_safe(name_node, tmp, &dev->name_node->list, list) + __netdev_name_node_alt_destroy(name_node); +} + /* Device list insertion */ static void list_netdevice(struct net_device *dev) { @@ -262,7 +378,7 @@ static void list_netdevice(struct net_de write_lock_bh(&dev_base_lock); list_add_tail_rcu(&dev->dev_list, &net->dev_base_head); - hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name)); + netdev_name_node_add(net, dev->name_node); hlist_add_head_rcu(&dev->index_hlist, dev_index_hash(net, dev->ifindex)); write_unlock_bh(&dev_base_lock); @@ -280,7 +396,7 @@ static void unlist_netdevice(struct net_ /* Unlink dev from the device chain */ write_lock_bh(&dev_base_lock); list_del_rcu(&dev->dev_list); - hlist_del_rcu(&dev->name_hlist); + netdev_name_node_del(dev->name_node); hlist_del_rcu(&dev->index_hlist); write_unlock_bh(&dev_base_lock); @@ -673,14 +789,10 @@ EXPORT_SYMBOL_GPL(dev_fill_metadata_dst) struct net_device *__dev_get_by_name(struct net *net, const char *name) { - struct net_device *dev; - struct hlist_head *head = dev_name_hash(net, name); - - hlist_for_each_entry(dev, head, name_hlist) - if (!strncmp(dev->name, name, IFNAMSIZ)) - return dev; + struct netdev_name_node *node_name; - return NULL; + node_name = netdev_name_node_lookup(net, name); + return node_name ? node_name->dev : NULL; } EXPORT_SYMBOL(__dev_get_by_name); @@ -698,14 +810,10 @@ EXPORT_SYMBOL(__dev_get_by_name); struct net_device *dev_get_by_name_rcu(struct net *net, const char *name) { - struct net_device *dev; - struct hlist_head *head = dev_name_hash(net, name); - - hlist_for_each_entry_rcu(dev, head, name_hlist) - if (!strncmp(dev->name, name, IFNAMSIZ)) - return dev; - - return NULL; + struct netdev_name_node *node_name; + + node_name = netdev_name_node_lookup_rcu(net, name); + return node_name ? node_name->dev : NULL; } EXPORT_SYMBOL(dev_get_by_name_rcu); @@ -1166,13 +1274,13 @@ rollback: netdev_adjacent_rename_links(dev, oldname); write_lock_bh(&dev_base_lock); - hlist_del_rcu(&dev->name_hlist); + netdev_name_node_del(dev->name_node); write_unlock_bh(&dev_base_lock); synchronize_rcu(); write_lock_bh(&dev_base_lock); - hlist_add_head_rcu(&dev->name_hlist, dev_name_hash(net, dev->name)); + netdev_name_node_add(net, dev->name_node); write_unlock_bh(&dev_base_lock); ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev); @@ -9379,6 +9487,9 @@ static void rollback_registered_many(str dev_uc_flush(dev); dev_mc_flush(dev); + netdev_name_node_alt_flush(dev); + netdev_name_node_free(dev->name_node); + if (dev->netdev_ops->ndo_uninit) dev->netdev_ops->ndo_uninit(dev); @@ -9853,6 +9964,10 @@ int register_netdevice(struct net_device if (ret < 0) goto out; + dev->name_node = netdev_name_node_head_alloc(dev); + if (!dev->name_node) + goto out; + /* Init, if this function is available */ if (dev->netdev_ops->ndo_init) { ret = dev->netdev_ops->ndo_init(dev); @@ -9990,6 +10105,8 @@ out: return ret; err_uninit: + if (dev->name_node) + netdev_name_node_free(dev->name_node); if (dev->netdev_ops->ndo_uninit) dev->netdev_ops->ndo_uninit(dev); if (dev->priv_destructor) Index: b/net/core/net-procfs.c =================================================================== --- a/net/core/net-procfs.c +++ b/net/core/net-procfs.c @@ -20,8 +20,8 @@ static inline struct net_device *dev_fro struct hlist_head *h; unsigned int count = 0, offset = get_offset(*pos); - h = &net->dev_name_head[get_bucket(*pos)]; - hlist_for_each_entry_rcu(dev, h, name_hlist) { + h = &net->dev_index_head[get_bucket(*pos)]; + hlist_for_each_entry_rcu(dev, h, index_hlist) { if (++count == offset) return dev; } Index: b/net/core/rtnetlink.c =================================================================== --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1750,6 +1750,9 @@ static const struct nla_policy ifla_poli [IFLA_CARRIER_DOWN_COUNT] = { .type = NLA_U32 }, [IFLA_MIN_MTU] = { .type = NLA_U32 }, [IFLA_MAX_MTU] = { .type = NLA_U32 }, + [IFLA_PROP_LIST] = { .type = NLA_NESTED }, + [IFLA_ALT_IFNAME] = { .type = NLA_STRING, + .len = ALTIFNAMSIZ - 1 }, }; static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { @@ -3408,6 +3411,103 @@ out: return err; } +static int rtnl_alt_ifname(int cmd, struct net_device *dev, struct nlattr *attr, + bool *changed, struct netlink_ext_ack *extack) +{ + char *alt_ifname; + int err; + + err = nla_validate(attr, attr->nla_len, IFLA_MAX, ifla_policy, extack); + if (err) + return err; + + alt_ifname = nla_data(attr); + if (cmd == RTM_NEWLINKPROP) { + alt_ifname = kstrdup(alt_ifname, GFP_KERNEL); + if (!alt_ifname) + return -ENOMEM; + err = netdev_name_node_alt_create(dev, alt_ifname); + if (err) { + kfree(alt_ifname); + return err; + } + } else if (cmd == RTM_DELLINKPROP) { + err = netdev_name_node_alt_destroy(dev, alt_ifname); + if (err) + return err; + } else { + WARN_ON(1); + return 0; + } + + *changed = true; + return 0; +} + +static int rtnl_linkprop(int cmd, struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) +{ + struct net *net = sock_net(skb->sk); + struct nlattr *tb[IFLA_MAX + 1]; + struct net_device *dev; + struct ifinfomsg *ifm; + bool changed = false; + struct nlattr *attr; + int err, rem; + + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy, extack); + if (err) + return err; + + err = rtnl_ensure_unique_netns(tb, extack, true); + if (err) + return err; + + ifm = nlmsg_data(nlh); + if (ifm->ifi_index > 0) { + dev = __dev_get_by_index(net, ifm->ifi_index); + } else if (tb[IFLA_IFNAME]) { + char ifname[IFNAMSIZ]; + + nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); + dev = __dev_get_by_name(net, ifname); + } else { + return -EINVAL; + } + + if (!dev) + return -ENODEV; + + if (!tb[IFLA_PROP_LIST]) + return 0; + + nla_for_each_nested(attr, tb[IFLA_PROP_LIST], rem) { + switch (nla_type(attr)) { + case IFLA_ALT_IFNAME: + err = rtnl_alt_ifname(cmd, dev, attr, &changed, extack); + if (err) + return err; + break; + } + } + + if (changed) + netdev_state_change(dev); + return 0; +} + +static int rtnl_newlinkprop(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) +{ + return rtnl_linkprop(RTM_NEWLINKPROP, skb, nlh, extack); +} + +static int rtnl_dellinkprop(struct sk_buff *skb, struct nlmsghdr *nlh, + struct netlink_ext_ack *extack) +{ + return rtnl_linkprop(RTM_DELLINKPROP, skb, nlh, extack); +} + static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) { struct net *net = sock_net(skb->sk); @@ -5370,6 +5470,9 @@ void __init rtnetlink_init(void) rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0); rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0); + rtnl_register(PF_UNSPEC, RTM_NEWLINKPROP, rtnl_newlinkprop, NULL, 0); + rtnl_register(PF_UNSPEC, RTM_DELLINKPROP, rtnl_dellinkprop, NULL, 0); + rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0); rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0); rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0); Index: b/security/selinux/nlmsgtab.c =================================================================== --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -83,6 +83,8 @@ static const struct nlmsg_perm nlmsg_rou { RTM_NEWNEXTHOP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_DELNEXTHOP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_GETNEXTHOP, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_NEWLINKPROP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, + { RTM_DELLINKPROP, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, }; static const struct nlmsg_perm nlmsg_tcpdiag_perms[] = @@ -166,7 +168,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 * structures at the top of this file with the new mappings * before updating the BUILD_BUG_ON() macro! */ - BUILD_BUG_ON(RTM_MAX != (RTM_NEWNEXTHOP + 3)); + BUILD_BUG_ON(RTM_MAX != (RTM_NEWLINKPROP + 3)); err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, sizeof(nlmsg_route_perms)); break;
最新发布
12-25
逐行解释代码,并说明 #define NUM_RRS 5 /*****************************************************************************/ struct dns_rr{ char name[NAME_SIZE]; uint16 type; uint16 class; uint32 ttl; uint16 rdatalen; char data[NAME_SIZE]; }; /*****************************************************************************/ union header_flags { uint16 flags; struct { unsigned short int rcode:4; unsigned short int unused:3; unsigned short int recursion_avail:1; unsigned short int want_recursion:1; unsigned short int truncated:1; unsigned short int authorative:1; unsigned short int opcode:4; unsigned short int question:1; } f; }; /*****************************************************************************/ struct dns_header_s{ uint16 id; union header_flags flags; uint16 qdcount; uint16 ancount; uint16 nscount; uint16 arcount; }; /*****************************************************************************/ struct dns_message{ struct dns_header_s header; struct dns_rr question[NUM_RRS]; struct dns_rr answer[NUM_RRS]; }; /*****************************************************************************/ typedef struct dns_request_s{ char cname[NAME_SIZE]; char ip[46]; /* by wdl, 01Mar11, change to 46 to fix IPv6 addr length * for example (xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255) */ int ttl; int time_pending; /* request age in seconds */ /* the actual dns request that was recieved */ struct dns_message message; /* where the request came from */ struct in6_addr src_addr; /* by wdl, 01Mar11, change to support ipv6 */ int src_port; /* the orginal packet */ char original_buf[MAX_PACKET_SIZE]; int numread; char *here; /* next node in list */ struct dns_request_s *next; }dns_request_t; /*****************************************************************************/ /* TYPE values */ enum{ A = 1, /* a host address */ NS, /* an authoritative name server */ MD, /* a mail destination (Obsolete - use MX) */ MF, /* */ CNAME, /* the canonical name for an alias */ SOA, /* marks the start of a zone of authority */ MB, /* a mailbox domain name (EXPERIMENTAL) */ MG, /* */ MR, /* */ NUL, /* */ WKS, /* a well known service description */ PTR, /* a domain name pointer */ HINFO, /* host information */ MINFO, /* mailbox or mail list information */ MX, /* mail exchange */ TXT, /* text strings */ AAAA = 0x1c /* IPv6 A */ }; /* CLASS values */ enum{ IN = 1, /* the Internet */ CS, CH, HS }; /* OPCODE values */ enum{ QUERY, IQUERY, STATUS }; /* ** ** cache.c - cache handling routines ** ** Part of the dproxy package by Matthew Pratt. ** ** Copyright 1999 Matthew Pratt <mattpratt@yahoo.com> ** ** This software is licensed under the terms of the GNU General ** Public License (GPL). Please see the file COPYING for details. ** ** */ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <time.h> #include <sys/file.h> #include <sys/types.h> #include <dirent.h> #include <ctype.h> #include <unistd.h> #include <signal.h> #include "cache.h" #include "conf.h" /** function prototypes for private functions*/ static int cache_byname(FILE * , char *, char *); /***************************************************************************** * search for a host by its name. * * This function first searches the cache for an entry. If the entry * was not found there, we will look into a dhcp "leases" file. * * @arg name - name to find. * @arg ip - pointer to a buffer where to put the ip adress. * * @return 0 if an entry was found, 1 if not. *****************************************************************************/ int cache_lookup_name(char *name, char ip[BUF_SIZE]) { FILE * fp; debug( "cache_lookup_name(%s)\n", name); /** check the cache */ if( (fp = fopen( config.cache_file , "r")) != NULL) { int result = 0; result = cache_byname(fp,name, ip); fclose(fp); if( result > 0 ) { return 1; } } return 0; } /***************************************************************************** * lookup a hostname in the cache file. * * This function will not lock the cache ! * * @arg fp - open file pointer for the cache file. * @arg name - name to find. * @arg ip - pointer to a buffer where to put the ip adress. * * @return 0 if an entry was found, 1 if not. *****************************************************************************/ static int cache_byname(FILE * fp, char *name, char ip[BUF_SIZE]) { char line[BUF_SIZE]; char *token; int i = 0; ip[0] = 0; /** make shure we are at the start of the cache */ rewind(fp); while( fgets(line, BUF_SIZE, fp) ){ token = strtok( line, " "); if( !strcasecmp( token, name) ){ token = strtok( NULL, " "); while( isalnum(*token) || (*token=='.'))ip[i++] = *token++; ip[i] = 0; return 1; } } return 0; } /*****************************************************************************/ int cache_lookup_ip(char *ip, char result[BUF_SIZE]) { FILE *fp; char line[BUF_SIZE]; char *token; int i = 0; if( ip[0] == 0 )return 0; result[0] = 0; fp = fopen( config.cache_file , "r"); if(!fp)return 0; while( fgets(line, BUF_SIZE, fp) ){ strtok( line, " "); token = strtok( NULL, " "); if( !strncasecmp( token, ip, strlen(ip) ) ){ while( isalnum(line[i]) || (line[i]=='.') || (line[i] == '-'))result[i] = line[i++]; result[i] = 0; fclose(fp); return 1; } } fclose(fp); return 0; } #if 0 /***************************************************************************** * save the name to the list. * * *****************************************************************************/ void cache_name_append(char *name, char *ip) { FILE *fp; char dummy[BUF_SIZE]; fp = fopen( config.cache_file, "a"); if(!fp){ debug("Could not open cache file '%s' for writing", config.cache_file); return; } /** check if another process already added this host to the cache */ if( cache_byname(fp, name, dummy) != 0 ) { fclose(fp); return; } /** make shure that we at the end of the file. */ fseek(fp,0,SEEK_END); /** write new entry */ fprintf( fp, "%s %s %ld\n", name, ip, time(NULL) ); fclose(fp); } #endif /*****************************************************************************/ void cache_purge(int older_than) { FILE *in_fp, *out_fp; char line[BUF_SIZE]; char old_cache[1024]; char *name, *ip, *time_made; #if 0 //BRCM in_fp = fopen( config.cache_file , "r"); if(!in_fp){ debug_perror("Could not open old cache file"); /*return;*/ } if( in_fp ) { sprintf( old_cache, "%s.old", config.cache_file ); if( rename( config.cache_file, old_cache ) < 0 ){ debug_perror("Could not move cache file"); fclose(in_fp); return; } } #endif //printf("%s %d config.cache_file = %s\r\n",__FUNCTION__,__LINE__,config.cache_file); //out_fp = fopen(config.cache_file , "w"); /* changed by ZQQ, 19Apr2011 */ out_fp = fopen(config.cache_file , "w+"); if(!out_fp){ #if 0 //BRCM if( in_fp ) { fclose(in_fp); } #endif debug_perror("Could not open new cache file"); return; } /* changed by ZQQ, 20May2011 */ #if 0 cache_add_hosts_entries(out_fp); #endif cache_add_dhcp_entries(out_fp); #if 0 //BRCM if( in_fp ) { while( fgets(line, BUF_SIZE, in_fp) ){ name = strtok( line, " "); ip = strtok( NULL, " "); time_made = strtok( NULL, " "); if(!time_made)continue; if( time(NULL) - atoi( time_made ) < older_than ) fprintf( out_fp, "%s %s %s", name, ip, time_made ); } fclose(in_fp); unlink(old_cache); } #endif fclose(out_fp); } /*****************************************************************************/ void cache_add_hosts_entries(FILE *cache_file) { FILE *hosts_fp; char line[BUF_SIZE]; char *ip, *name; debug("cache_add_hosts_entreies()\n"); printf("%s %d config.hosts_file = %s\r\n", __FUNCTION__,__LINE__,config.hosts_file); hosts_fp = fopen( config.hosts_file , "r"); if( !hosts_fp ) { debug_perror("can not open 'hosts'-file "); return; } while( fgets(line, BUF_SIZE, hosts_fp) ){ line[strlen(line) - 1] = 0; /* get rid of '\n' */ ip = strtok( line, " \t"); if( ip == NULL ) continue; /* ignore blank lines */ if( ip[0] == '#' )continue; /* ignore comments */ while( (name = strtok( NULL, " \t" )) ){ if(name[0] == '#')break; fprintf( cache_file, "%s %s %ld\n", name, ip, 0L ); } } fclose(hosts_fp); debug("cache_add_hosts_entreies(): done\n"); } static void remove_delimitor( char *s) { char *p1, *p2; p1 = p2 = s; while ( *p1 != '\0' || *(p1+1) != '\0') { if (*p1 != '\0') { *p2 = *p1; p2++; } p1++; } *p2='\0'; } /* find_pid_by_name() * * This finds the pid of the specified process. * Currently, it's implemented by rummaging through * the proc filesystem. * * Returns a list of all matching PIDs */ #define READ_BUF_SIZE 128 static pid_t* find_pid_by_name( char* pidName) { DIR *dir; struct dirent *next; pid_t* pidList=NULL; int i=0; /*FILE *status */ FILE *cmdline; char filename[READ_BUF_SIZE]; char buffer[READ_BUF_SIZE]; /* char name[READ_BUF_SIZE]; */ dir = opendir("/proc"); if (!dir) { debug("Cannot open /proc"); return NULL; } while ((next = readdir(dir)) != NULL) { /* re-initialize buffers */ memset(filename, 0, sizeof(filename)); memset(buffer, 0, sizeof(buffer)); /* Must skip ".." since that is outside /proc */ if (strcmp(next->d_name, "..") == 0) continue; /* If it isn't a number, we don't want it */ if (!isdigit(*next->d_name)) continue; /* sprintf(filename, "/proc/%s/status", next->d_name); */ /* read /porc/<pid>/cmdline instead to get full cmd line */ sprintf(filename, "/proc/%s/cmdline", next->d_name); if (! (cmdline = fopen(filename, "r")) ) { continue; } if (fgets(buffer, READ_BUF_SIZE-1, cmdline) == NULL) { fclose(cmdline); continue; } fclose(cmdline); /* Buffer should contain a string like "Name: binary_name" */ /*sscanf(buffer, "%*s %s", name);*/ /* buffer contains full commandline params separted by '\0' */ remove_delimitor(buffer); if (strstr(buffer, pidName) != NULL) { pidList=realloc( pidList, sizeof(pid_t) * (i+2)); if (!pidList) { debug("Out of memeory!\n"); closedir(dir); return NULL; } pidList[i++]=strtol(next->d_name, NULL, 0); } } closedir(dir); if (pidList) pidList[i]=0; else if ( strcmp(pidName, "init")==0) { /* If we found nothing and they were trying to kill "init", * guess PID 1 and call it good... Perhaps we should simply * exit if /proc isn't mounted, but this will do for now. */ pidList=realloc( pidList, sizeof(pid_t)); if (!pidList) { debug("Out of memeory!\n"); return NULL; } pidList[0]=1; } else { pidList=realloc( pidList, sizeof(pid_t)); if (!pidList) { debug("Out of memeory!\n"); return NULL; } pidList[0]=-1; } return pidList; } static int bcmGetPid(char * command) { char cmdline[128], *p1, *p2; pid_t *pid = NULL; int ret = 0; p1 = command; p2 = cmdline; while ( *p1 != '\0') { if (*p1 != ' ') { *p2 = *p1; p2++; } p1++; } *p2='\0'; pid = find_pid_by_name(cmdline); if ( pid != NULL ) { ret = (int)(*pid); free(pid); } return ret; } struct lease_t { unsigned char chaddr[16]; u_int32_t yiaddr; u_int32_t expires; char hostname[64]; }; #define ETHER_ISNULLADDR(ea) ((((char *)(ea))[0] | \ ((char *)(ea))[1] | \ ((char *)(ea))[2] | \ ((char *)(ea))[3] | \ ((char *)(ea))[4] | \ ((char *)(ea))[5]) == 0) void cache_add_dhcp_entries(FILE *cache_file) { FILE *dhcpleases_fp; char line[BUF_SIZE]; char *ip, *name; struct lease_t lease; struct in_addr ipAddr; debug("cache_add_dhcp_entreies()\n"); int dpid = bcmGetPid("dhcpd"); if (dpid == -1) { // dhcp server not running return; } kill(dpid, SIGUSR1); printf("%s %d config.dhcp_lease_file = %s\r\n", __FUNCTION__, __LINE__, config.dhcp_lease_file); dhcpleases_fp = fopen( config.dhcp_lease_file , "r"); if( !dhcpleases_fp ) { debug_perror("can not open 'udhcpd_leases'-file "); return; } while (fread(&lease, sizeof(lease), 1, dhcpleases_fp)){ /* Do not display reserved leases */ if (ETHER_ISNULLADDR(lease.chaddr)) { continue; } ipAddr.s_addr = lease.yiaddr; fprintf( cache_file, "%s.%s %s %ld\n", lease.hostname, config.domain_name, inet_ntoa(ipAddr), 0L ); } fclose(dhcpleases_fp); debug("cache_add_dhcp_entreies(): done\n"); }
09-24
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值