1/*
2 * Copyright (c) 2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2007 Lawrence Livermore National Lab
4 *
5 * This software is available to you under a choice of one of two
6 * licenses.  You may choose to be licensed under the terms of the GNU
7 * General Public License (GPL) Version 2, available from the file
8 * COPYING in the main directory of this source tree, or the
9 * OpenIB.org BSD license below:
10 *
11 *     Redistribution and use in source and binary forms, with or
12 *     without modification, are permitted provided that the following
13 *     conditions are met:
14 *
15 *      - Redistributions of source code must retain the above
16 *        copyright notice, this list of conditions and the following
17 *        disclaimer.
18 *
19 *      - Redistributions in binary form must reproduce the above
20 *        copyright notice, this list of conditions and the following
21 *        disclaimer in the documentation and/or other materials
22 *        provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 *
33 */
34
35#define _GNU_SOURCE
36#include <stdio.h>
37#include <errno.h>
38#include <string.h>
39#include <stdlib.h>
40#include <stdarg.h>
41#include <sys/types.h>
42#include <sys/stat.h>
43#include <unistd.h>
44#include <ctype.h>
45#ifdef HAVE_CONFIG_H
46#include <config.h>
47#endif
48
49#include <complib/cl_nodenamemap.h>
50
51static int map_name(void *cxt, uint64_t guid, char *p)
52{
53	cl_qmap_t *map = cxt;
54	name_map_item_t *item;
55
56	p = strtok(p, "\"#");
57	if (!p)
58		return 0;
59
60	item = malloc(sizeof(*item));
61	if (!item)
62		return -1;
63	item->guid = guid;
64	item->name = strdup(p);
65	cl_qmap_insert(map, item->guid, (cl_map_item_t *)item);
66	return 0;
67}
68
69nn_map_t *
70open_node_name_map(char *node_name_map)
71{
72	nn_map_t *map;
73
74	if (!node_name_map) {
75#ifdef HAVE_DEFAULT_NODENAME_MAP
76		struct stat buf;
77		node_name_map = HAVE_DEFAULT_NODENAME_MAP;
78		if (stat(node_name_map, &buf))
79			return NULL;
80#else
81		return NULL;
82#endif /* HAVE_DEFAULT_NODENAME_MAP */
83	}
84
85	map = malloc(sizeof(*map));
86	if (!map)
87		return NULL;
88	cl_qmap_init(map);
89
90	if (parse_node_map(node_name_map, map_name, map)) {
91		fprintf(stderr,
92			"WARNING failed to open node name map \"%s\" (%s)\n",
93			node_name_map, strerror(errno));
94			close_node_name_map(map);
95			return NULL;
96	}
97
98	return map;
99}
100
101void
102close_node_name_map(nn_map_t *map)
103{
104	name_map_item_t *item = NULL;
105
106	if (!map)
107		return;
108
109	item = (name_map_item_t *)cl_qmap_head(map);
110	while (item != (name_map_item_t *)cl_qmap_end(map)) {
111		item = (name_map_item_t *)cl_qmap_remove(map, item->guid);
112		free(item->name);
113		free(item);
114		item = (name_map_item_t *)cl_qmap_head(map);
115	}
116	free(map);
117}
118
119char *
120remap_node_name(nn_map_t *map, uint64_t target_guid, char *nodedesc)
121{
122	char *rc = NULL;
123	name_map_item_t *item = NULL;
124
125	if (!map)
126		goto done;
127
128	item = (name_map_item_t *)cl_qmap_get(map, target_guid);
129	if (item != (name_map_item_t *)cl_qmap_end(map))
130		rc = strdup(item->name);
131
132done:
133	if (rc == NULL)
134		rc = strdup(clean_nodedesc(nodedesc));
135	return (rc);
136}
137
138char *
139clean_nodedesc(char *nodedesc)
140{
141	int i = 0;
142
143	nodedesc[63] = '\0';
144	while (nodedesc[i]) {
145		if (!isprint(nodedesc[i]))
146			nodedesc[i] = ' ';
147		i++;
148	}
149
150	return (nodedesc);
151}
152
153int parse_node_map(const char *file_name,
154		   int (*create)(void *, uint64_t, char *), void *cxt)
155{
156	char line[256];
157	FILE *f;
158
159	if (!(f = fopen(file_name, "r")))
160		return -1;
161
162	while (fgets(line, sizeof(line), f)) {
163		uint64_t guid;
164		char *p, *e;
165
166		p = line;
167		while (isspace(*p))
168			p++;
169		if (*p == '\0' || *p == '\n' || *p == '#')
170			continue;
171
172		guid = strtoull(p, &e, 0);
173		if (e == p || (!isspace(*e) && *e != '#' && *e != '\0')) {
174			fclose(f);
175			return -1;
176		}
177
178		p = e;
179		while (isspace(*p))
180			p++;
181
182		e = strpbrk(p, "\n");
183		if (e)
184			*e = '\0';
185
186		if (create(cxt, guid, p)) {
187			fclose(f);
188			return -1;
189		}
190	}
191
192	fclose(f);
193	return 0;
194}
195