source: mainline/uspace/srv/devman/match.c@ b19e892

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since b19e892 was b19e892, checked in by Jakub Jermar <jakub@…>, 8 years ago

Merge open() with posix_open() and provide vfs_lookup_open() instead

vfs_lookup_open() is really just a convenience wrapper around
vfs_lookup() and vfs_open().

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[e2b9a993]1/*
2 * Copyright (c) 2010 Lenka Trochtova
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup devman
30 * @{
31 */
[38b3baf]32
[6afc9d7]33#include <errno.h>
[a60e90b]34#include <io/log.h>
[c47e1a8]35#include <str.h>
[a60e90b]36#include <str_error.h>
37#include <sys/types.h>
[23a0368]38#include <vfs/vfs.h>
[e2b9a993]39
40#include "devman.h"
[a60e90b]41#include "match.h"
[e2b9a993]42
[aed3e6a]43#define COMMENT '#'
44
[cc70d57]45/** Compute compound score of driver and device.
46 *
47 * @param driver Match id of the driver.
48 * @param device Match id of the device.
49 * @return Compound score.
50 * @retval 0 No match at all.
51 */
52static int compute_match_score(match_id_t *driver, match_id_t *device)
53{
54 if (str_cmp(driver->id, device->id) == 0) {
55 /*
[4006447]56 * The strings match, return the product of their scores.
[cc70d57]57 */
58 return driver->score * device->score;
59 } else {
60 /*
61 * Different strings, return zero.
62 */
63 return 0;
64 }
65}
66
[ba38f72c]67int get_match_score(driver_t *drv, dev_node_t *dev)
[38b3baf]68{
[b72efe8]69 link_t *drv_head = &drv->match_ids.ids.head;
70 link_t *dev_head = &dev->pfun->match_ids.ids.head;
[e2b9a993]71
[b72efe8]72 if (list_empty(&drv->match_ids.ids) ||
73 list_empty(&dev->pfun->match_ids.ids)) {
[e2b9a993]74 return 0;
[b72efe8]75 }
[e2b9a993]76
[cc70d57]77 /*
[4006447]78 * Go through all pairs, return the highest score obtained.
[cc70d57]79 */
80 int highest_score = 0;
[38b3baf]81
[b72efe8]82 link_t *drv_link = drv->match_ids.ids.head.next;
[cc70d57]83 while (drv_link != drv_head) {
84 link_t *dev_link = dev_head->next;
85 while (dev_link != dev_head) {
86 match_id_t *drv_id = list_get_instance(drv_link, match_id_t, link);
87 match_id_t *dev_id = list_get_instance(dev_link, match_id_t, link);
88
89 int score = compute_match_score(drv_id, dev_id);
90 if (score > highest_score) {
91 highest_score = score;
92 }
93
[e2b9a993]94 dev_link = dev_link->next;
95 }
96
[cc70d57]97 drv_link = drv_link->next;
98 }
[e2b9a993]99
[cc70d57]100 return highest_score;
[e2b9a993]101}
102
[a60e90b]103/** Read match id at the specified position of a string and set the position in
104 * the string to the first character following the id.
105 *
106 * @param buf The position in the input string.
107 * @return The match id.
108 */
109char *read_match_id(char **buf)
110{
111 char *res = NULL;
112 size_t len = get_nonspace_len(*buf);
113
114 if (len > 0) {
115 res = malloc(len + 1);
116 if (res != NULL) {
117 str_ncpy(res, len + 1, *buf, len);
118 *buf += len;
119 }
120 }
121
122 return res;
123}
124
125/**
126 * Read match ids and associated match scores from a string.
127 *
128 * Each match score in the string is followed by its match id.
129 * The match ids and match scores are separated by whitespaces.
130 * Neither match ids nor match scores can contain whitespaces.
131 *
132 * @param buf The string from which the match ids are read.
133 * @param ids The list of match ids into which the match ids and
134 * scores are added.
135 * @return True if at least one match id and associated match score
136 * was successfully read, false otherwise.
137 */
138bool parse_match_ids(char *buf, match_id_list_t *ids)
139{
140 int score = 0;
141 char *id = NULL;
142 int ids_read = 0;
143
144 while (true) {
145 /* skip spaces */
146 if (!skip_spaces(&buf))
147 break;
[aed3e6a]148
149 if (*buf == COMMENT) {
150 skip_line(&buf);
151 continue;
152 }
[a60e90b]153
154 /* read score */
155 score = strtoul(buf, &buf, 10);
156
157 /* skip spaces */
158 if (!skip_spaces(&buf))
159 break;
160
161 /* read id */
162 id = read_match_id(&buf);
163 if (NULL == id)
164 break;
165
166 /* create new match_id structure */
167 match_id_t *mid = create_match_id();
168 mid->id = id;
169 mid->score = score;
170
171 /* add it to the list */
172 add_match_id(ids, mid);
173
174 ids_read++;
175 }
176
177 return ids_read > 0;
178}
179
180/**
181 * Read match ids and associated match scores from a file.
182 *
183 * Each match score in the file is followed by its match id.
184 * The match ids and match scores are separated by whitespaces.
185 * Neither match ids nor match scores can contain whitespaces.
186 *
187 * @param buf The path to the file from which the match ids are read.
188 * @param ids The list of match ids into which the match ids and
189 * scores are added.
190 * @return True if at least one match id and associated match score
191 * was successfully read, false otherwise.
192 */
193bool read_match_ids(const char *conf_path, match_id_list_t *ids)
194{
195 log_msg(LOG_DEFAULT, LVL_DEBUG, "read_match_ids(conf_path=\"%s\")", conf_path);
196
197 bool suc = false;
198 char *buf = NULL;
199 bool opened = false;
200 int fd;
201 size_t len = 0;
[58898d1d]202 struct stat st;
[a60e90b]203
[b19e892]204 fd = vfs_lookup_open(conf_path, WALK_REGULAR, MODE_READ);
[a60e90b]205 if (fd < 0) {
206 log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to open `%s' for reading: %s.",
[6afc9d7]207 conf_path, str_error(errno));
[a60e90b]208 goto cleanup;
209 }
210 opened = true;
211
[23a0368]212 if (vfs_stat(fd, &st) != EOK) {
[58898d1d]213 log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to fstat %d: %s.", fd,
214 str_error(errno));
215 goto cleanup;
216 }
217 len = st.size;
[a60e90b]218 if (len == 0) {
219 log_msg(LOG_DEFAULT, LVL_ERROR, "Configuration file '%s' is empty.",
220 conf_path);
221 goto cleanup;
222 }
223
224 buf = malloc(len + 1);
225 if (buf == NULL) {
226 log_msg(LOG_DEFAULT, LVL_ERROR, "Memory allocation failed when parsing file "
227 "'%s'.", conf_path);
228 goto cleanup;
229 }
230
[58898d1d]231 ssize_t read_bytes = read(fd, (aoff64_t []) {0}, buf, len);
[a60e90b]232 if (read_bytes <= 0) {
[6afc9d7]233 log_msg(LOG_DEFAULT, LVL_ERROR, "Unable to read file '%s' (%d).", conf_path,
234 errno);
[a60e90b]235 goto cleanup;
236 }
237 buf[read_bytes] = 0;
238
239 suc = parse_match_ids(buf, ids);
240
241cleanup:
242 free(buf);
243
244 if (opened)
245 close(fd);
246
247 return suc;
248}
249
[38b3baf]250/** @}
251 */
Note: See TracBrowser for help on using the repository browser.