nmsg  0.9.0
alias.c
1 /*
2  * Copyright (c) 2009, 2012 by Farsight Security, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Import. */
18 
19 #include "private.h"
20 
21 /* Macros. */
22 
23 #define ALIAS_FILE_OPERATOR NMSG_ETCDIR "/nmsg.opalias"
24 #define ALIAS_FILE_GROUP NMSG_ETCDIR "/nmsg.gralias"
25 
26 #define ALIAS_SZ_INIT 16
27 #define MAX_LINE_SZ 1024
28 
29 struct nmsg_alias {
30  size_t max_idx;
31  char **value;
32 };
33 
34 static int nmsg_alias_initialized = 0;
35 static struct nmsg_alias alias_operator;
36 static struct nmsg_alias alias_group;
37 
38 /* Forward. */
39 
40 static nmsg_res alias_init(struct nmsg_alias *, const char *fname);
41 static nmsg_res alias_resize(struct nmsg_alias *, unsigned n);
42 static void alias_free(struct nmsg_alias *);
43 
44 /* Functions. */
45 
46 const char *
47 nmsg_alias_by_key(nmsg_alias_e ae, unsigned key) {
48  struct nmsg_alias *al = NULL;
49 
50  if (ae == nmsg_alias_operator)
51  al = &alias_operator;
52  else if (ae == nmsg_alias_group)
53  al = &alias_group;
54 
55  assert(al != NULL);
56 
57  if (key <= al->max_idx)
58  return (al->value[key]);
59 
60  return (NULL);
61 }
62 
63 unsigned
64 nmsg_alias_by_value(nmsg_alias_e ae, const char *value) {
65  struct nmsg_alias *al = NULL;
66 
67  if (ae == nmsg_alias_operator)
68  al = &alias_operator;
69  else if (ae == nmsg_alias_group)
70  al = &alias_group;
71 
72  assert(al != NULL);
73 
74  for (unsigned i = 0; i <= al->max_idx; i++)
75  if (al->value[i] != NULL &&
76  strcasecmp(value, al->value[i]) == 0)
77  return (i);
78 
79  return (0);
80 }
81 
83 _nmsg_alias_init(void) {
84  nmsg_res res;
85 
86  if (nmsg_alias_initialized == 0) {
87  res = alias_init(&alias_operator, ALIAS_FILE_OPERATOR);
88  if (res != nmsg_res_success)
89  return (res);
90 
91  res = alias_init(&alias_group, ALIAS_FILE_GROUP);
92  if (res != nmsg_res_success)
93  return (res);
94 
95  nmsg_alias_initialized = 1;
96  }
97 
98  return (nmsg_res_success);
99 }
100 
101 void
102 _nmsg_alias_fini(void) {
103  if (nmsg_alias_initialized == 1) {
104  alias_free(&alias_operator);
105  alias_free(&alias_group);
106  nmsg_alias_initialized = 0;
107  }
108 }
109 
110 /* Private. */
111 
112 static nmsg_res
113 alias_init(struct nmsg_alias *al, const char *fname) {
114  FILE *fp;
115  char line[MAX_LINE_SZ];
116  char *saveptr, *str_key, *str_value;
117  char *t;
118  unsigned key;
119  nmsg_res res;
120 
121  res = nmsg_res_success;
122 
123  al->value = malloc(sizeof(*(al->value)) * (ALIAS_SZ_INIT + 1));
124  if (al->value == NULL)
125  return (nmsg_res_failure);
126  al->max_idx = ALIAS_SZ_INIT;
127  for (unsigned i = 0; i <= al->max_idx; i++)
128  al->value[i] = NULL;
129 
130  fp = fopen(fname, "r");
131  if (fp == NULL)
132  /* file may not exist */
133  return (nmsg_res_success);
134 
135  while (fgets(line, sizeof(line), fp) != NULL) {
136  str_key = strtok_r(line, " \t", &saveptr);
137  str_value = strtok_r(NULL, " \t\n", &saveptr);
138  if (str_key == NULL || str_value == NULL) {
139  res = nmsg_res_failure;
140  break;
141  }
142 
143  key = (unsigned) strtoul(str_key, &t, 0);
144  if (*t != '\0') {
145  res = nmsg_res_failure;
146  break;
147  }
148 
149  if (key > al->max_idx) {
150  if (alias_resize(al, key) != nmsg_res_success) {
151  res = nmsg_res_failure;
152  break;
153  }
154  }
155 
156  al->value[key] = strdup(str_value);
157  }
158 
159  fclose(fp);
160  return (res);
161 }
162 
163 static nmsg_res
164 alias_resize(struct nmsg_alias *al, unsigned n) {
165  unsigned max_idx;
166  void *tmp;
167 
168  n += 1;
169 
170  if (n > al->max_idx) {
171  max_idx = al->max_idx * 2;
172  if (n > max_idx)
173  max_idx = n + 1;
174 
175  tmp = al->value;
176  al->value = realloc(al->value, (max_idx + 1) * sizeof(*(al->value)));
177  if (al->value == NULL) {
178  free(tmp);
179  al->max_idx = 0;
180  return (nmsg_res_failure);
181  }
182  for (unsigned i = al->max_idx + 1; i <= max_idx; i++)
183  al->value[i] = NULL;
184  al->max_idx = max_idx;
185  }
186  return (nmsg_res_success);
187 }
188 
189 static void
190 alias_free(struct nmsg_alias *al) {
191  for (unsigned i = 0; i <= al->max_idx; i++)
192  if (al->value[i] != NULL)
193  free(al->value[i]);
194  free(al->value);
195  al->value = NULL;
196  al->max_idx = 0;
197 }
nmsg_res
nmsg result code
Definition: res.h:25
success
Definition: res.h:26
unsigned nmsg_alias_by_value(nmsg_alias_e ae, const char *value)
Look up an alias by name.
Definition: alias.c:64
operator ID -> operator name
Definition: alias.h:32
generic failure
Definition: res.h:27
const char * nmsg_alias_by_key(nmsg_alias_e ae, unsigned key)
Look up an alias by key.
Definition: alias.c:47
nmsg_alias_e
Alias type.
Definition: alias.h:31
group ID -> group name
Definition: alias.h:33