1219820Sjeff/*
2219820Sjeff * Copyright (c) 2008 Voltaire, Inc. All rights reserved.
3219820Sjeff * Copyright (c) 2007 Lawrence Livermore National Lab
4219820Sjeff *
5219820Sjeff * This software is available to you under a choice of one of two
6219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
7219820Sjeff * General Public License (GPL) Version 2, available from the file
8219820Sjeff * COPYING in the main directory of this source tree, or the
9219820Sjeff * OpenIB.org BSD license below:
10219820Sjeff *
11219820Sjeff *     Redistribution and use in source and binary forms, with or
12219820Sjeff *     without modification, are permitted provided that the following
13219820Sjeff *     conditions are met:
14219820Sjeff *
15219820Sjeff *      - Redistributions of source code must retain the above
16219820Sjeff *        copyright notice, this list of conditions and the following
17219820Sjeff *        disclaimer.
18219820Sjeff *
19219820Sjeff *      - Redistributions in binary form must reproduce the above
20219820Sjeff *        copyright notice, this list of conditions and the following
21219820Sjeff *        disclaimer in the documentation and/or other materials
22219820Sjeff *        provided with the distribution.
23219820Sjeff *
24219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31219820Sjeff * SOFTWARE.
32219820Sjeff *
33219820Sjeff */
34219820Sjeff
35219820Sjeff#define _GNU_SOURCE
36219820Sjeff#include <stdio.h>
37219820Sjeff#include <errno.h>
38219820Sjeff#include <string.h>
39219820Sjeff#include <stdlib.h>
40219820Sjeff#include <stdarg.h>
41219820Sjeff#include <sys/types.h>
42219820Sjeff#include <sys/stat.h>
43219820Sjeff#include <unistd.h>
44219820Sjeff#include <ctype.h>
45219820Sjeff#ifdef HAVE_CONFIG_H
46219820Sjeff#include <config.h>
47219820Sjeff#endif
48219820Sjeff
49219820Sjeff#include <complib/cl_nodenamemap.h>
50219820Sjeff
51219820Sjeffstatic int map_name(void *cxt, uint64_t guid, char *p)
52219820Sjeff{
53219820Sjeff	cl_qmap_t *map = cxt;
54219820Sjeff	name_map_item_t *item;
55219820Sjeff
56219820Sjeff	p = strtok(p, "\"#");
57219820Sjeff	if (!p)
58219820Sjeff		return 0;
59219820Sjeff
60219820Sjeff	item = malloc(sizeof(*item));
61219820Sjeff	if (!item)
62219820Sjeff		return -1;
63219820Sjeff	item->guid = guid;
64219820Sjeff	item->name = strdup(p);
65219820Sjeff	cl_qmap_insert(map, item->guid, (cl_map_item_t *)item);
66219820Sjeff	return 0;
67219820Sjeff}
68219820Sjeff
69219820Sjeffnn_map_t *
70219820Sjeffopen_node_name_map(char *node_name_map)
71219820Sjeff{
72219820Sjeff	nn_map_t *map;
73219820Sjeff
74219820Sjeff	if (!node_name_map) {
75219820Sjeff#ifdef HAVE_DEFAULT_NODENAME_MAP
76219820Sjeff		struct stat buf;
77219820Sjeff		node_name_map = HAVE_DEFAULT_NODENAME_MAP;
78219820Sjeff		if (stat(node_name_map, &buf))
79219820Sjeff			return NULL;
80219820Sjeff#else
81219820Sjeff		return NULL;
82219820Sjeff#endif /* HAVE_DEFAULT_NODENAME_MAP */
83219820Sjeff	}
84219820Sjeff
85219820Sjeff	map = malloc(sizeof(*map));
86219820Sjeff	if (!map)
87219820Sjeff		return NULL;
88219820Sjeff	cl_qmap_init(map);
89219820Sjeff
90219820Sjeff	if (parse_node_map(node_name_map, map_name, map)) {
91219820Sjeff		fprintf(stderr,
92219820Sjeff			"WARNING failed to open node name map \"%s\" (%s)\n",
93219820Sjeff			node_name_map, strerror(errno));
94219820Sjeff			close_node_name_map(map);
95219820Sjeff			return NULL;
96219820Sjeff	}
97219820Sjeff
98219820Sjeff	return map;
99219820Sjeff}
100219820Sjeff
101219820Sjeffvoid
102219820Sjeffclose_node_name_map(nn_map_t *map)
103219820Sjeff{
104219820Sjeff	name_map_item_t *item = NULL;
105219820Sjeff
106219820Sjeff	if (!map)
107219820Sjeff		return;
108219820Sjeff
109219820Sjeff	item = (name_map_item_t *)cl_qmap_head(map);
110219820Sjeff	while (item != (name_map_item_t *)cl_qmap_end(map)) {
111219820Sjeff		item = (name_map_item_t *)cl_qmap_remove(map, item->guid);
112219820Sjeff		free(item->name);
113219820Sjeff		free(item);
114219820Sjeff		item = (name_map_item_t *)cl_qmap_head(map);
115219820Sjeff	}
116219820Sjeff	free(map);
117219820Sjeff}
118219820Sjeff
119219820Sjeffchar *
120219820Sjeffremap_node_name(nn_map_t *map, uint64_t target_guid, char *nodedesc)
121219820Sjeff{
122219820Sjeff	char *rc = NULL;
123219820Sjeff	name_map_item_t *item = NULL;
124219820Sjeff
125219820Sjeff	if (!map)
126219820Sjeff		goto done;
127219820Sjeff
128219820Sjeff	item = (name_map_item_t *)cl_qmap_get(map, target_guid);
129219820Sjeff	if (item != (name_map_item_t *)cl_qmap_end(map))
130219820Sjeff		rc = strdup(item->name);
131219820Sjeff
132219820Sjeffdone:
133219820Sjeff	if (rc == NULL)
134219820Sjeff		rc = strdup(clean_nodedesc(nodedesc));
135219820Sjeff	return (rc);
136219820Sjeff}
137219820Sjeff
138219820Sjeffchar *
139219820Sjeffclean_nodedesc(char *nodedesc)
140219820Sjeff{
141219820Sjeff	int i = 0;
142219820Sjeff
143219820Sjeff	nodedesc[63] = '\0';
144219820Sjeff	while (nodedesc[i]) {
145219820Sjeff		if (!isprint(nodedesc[i]))
146219820Sjeff			nodedesc[i] = ' ';
147219820Sjeff		i++;
148219820Sjeff	}
149219820Sjeff
150219820Sjeff	return (nodedesc);
151219820Sjeff}
152219820Sjeff
153219820Sjeffint parse_node_map(const char *file_name,
154219820Sjeff		   int (*create)(void *, uint64_t, char *), void *cxt)
155219820Sjeff{
156219820Sjeff	char line[256];
157219820Sjeff	FILE *f;
158219820Sjeff
159219820Sjeff	if (!(f = fopen(file_name, "r")))
160219820Sjeff		return -1;
161219820Sjeff
162219820Sjeff	while (fgets(line, sizeof(line), f)) {
163219820Sjeff		uint64_t guid;
164219820Sjeff		char *p, *e;
165219820Sjeff
166219820Sjeff		p = line;
167219820Sjeff		while (isspace(*p))
168219820Sjeff			p++;
169219820Sjeff		if (*p == '\0' || *p == '\n' || *p == '#')
170219820Sjeff			continue;
171219820Sjeff
172219820Sjeff		guid = strtoull(p, &e, 0);
173219820Sjeff		if (e == p || (!isspace(*e) && *e != '#' && *e != '\0')) {
174219820Sjeff			fclose(f);
175219820Sjeff			return -1;
176219820Sjeff		}
177219820Sjeff
178219820Sjeff		p = e;
179219820Sjeff		while (isspace(*p))
180219820Sjeff			p++;
181219820Sjeff
182219820Sjeff		e = strpbrk(p, "\n");
183219820Sjeff		if (e)
184219820Sjeff			*e = '\0';
185219820Sjeff
186219820Sjeff		if (create(cxt, guid, p)) {
187219820Sjeff			fclose(f);
188219820Sjeff			return -1;
189219820Sjeff		}
190219820Sjeff	}
191219820Sjeff
192219820Sjeff	fclose(f);
193219820Sjeff	return 0;
194219820Sjeff}
195