2 * (c) 2010 Cyrill Gorcunov, gorcunov@gmail.com
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 #include <sys/param.h>
30 #include <sys/types.h>
33 #include "backend-proto.h"
36 struct idutils_query_result
{
37 struct list_head list
;
39 struct backend_proto_item item
;
42 static struct idutils_query_result
*idutils_parse(char *name
, char *str
, unsigned long key
)
44 char *func
, *file
, *line
, *text
, *data_copy
;
45 struct idutils_query_result
*r
= NULL
;
50 data_copy
= xstrdup(str
);
52 func
= skip_spaces(name
);
53 file
= skip_spaces(strtok(data_copy
, ":"));
54 line
= skip_spaces(strtok(NULL
, ":"));
55 text
= skip_spaces(strtok(NULL
, "\r\n"));
57 if (!func
|| !file
|| !line
|| !text
) {
62 r
= xzalloc(sizeof(*r
));
64 r
->data_copy
= data_copy
;
66 r
->item
.func
= xstrdup(func
);
68 r
->item
.line
= atoi(line
);
71 INIT_LIST_HEAD(&r
->list
);
77 static void idutils_query_free(struct list_head
*head
)
79 struct idutils_query_result
*r
, *n
;
81 list_for_each_entry_safe(r
, n
, head
, list
) {
88 #define MAX_CMDLINE 256
89 static const char idutils_cmd
[] = "gid ";
90 static const char rebuild_cmd
[] = "mkid ";
92 static struct list_head
*idutils_query(struct backend_proto_query_params
*backend_params
)
94 char cmd_buf
[MAX_CMDLINE
] = { 0 };
96 struct idutils_query_result
*r
;
97 struct list_head
*head
= NULL
;
98 unsigned long key
= 0;
101 if (!backend_params
->u
.idutils
.name
||
102 !*backend_params
->u
.idutils
.name
)
105 #define strlcat_buf(str) strlcat(cmd_buf, str, sizeof(cmd_buf))
106 strlcat_buf(idutils_cmd
);
107 strlcat_buf(backend_params
->u
.idutils
.name
);
110 head
= xalloc(sizeof(*head
));
111 INIT_LIST_HEAD(head
);
113 pipe
= popen(cmd_buf
, "r");
115 warning("Can't open pipe for : %s", idutils_cmd
);
116 free(head
), head
= NULL
;
121 * We assume the output line will not exceed the buffer
122 * otherwise the parsing would not be strictly correct
124 while (fgets(read_buf
, sizeof(read_buf
), pipe
)) {
125 r
= idutils_parse(backend_params
->u
.idutils
.name
, read_buf
, key
++);
127 list_add(&r
->list
, head
);
130 warning("Closing pipe for parsing '%s' failed",
131 backend_params
->u
.idutils
.name
);
137 static struct idutils_query_result
*idutils_lookup_key(struct list_head
*head
, unsigned long key
)
139 struct idutils_query_result
*t
;
140 list_for_each_entry(t
, head
, list
) {
141 if (t
->item
.key
== key
)
147 static int idutils_backend_proto_lookup(struct list_head
*head
, struct backend_proto_item
*item
, unsigned long key
)
149 struct idutils_query_result
*t
= idutils_lookup_key(head
, key
);
152 memcpy(item
, &t
->item
, sizeof(*item
));
156 static int idutils_backend_proto_get(struct list_head
*entry
, struct backend_proto_item
*item
)
158 struct idutils_query_result
*t
= container_of(entry
, struct idutils_query_result
, list
);
159 memcpy(item
, &t
->item
, sizeof(*item
));
163 static void idutils_backend_proto_destory(struct list_head
*entry
)
165 struct idutils_query_result
*t
= container_of(entry
, struct idutils_query_result
, list
);
166 idutils_query_free(&t
->list
);
170 static void idutils_backend_proto_refresh(void)
174 pipe
= popen(rebuild_cmd
, "r");
176 warning("Can't open pipe for : %s", rebuild_cmd
);
181 warning("Closing pipe for parsing '%s' failed",
185 void init_id_utils_backend_proto(void)
187 static struct backend_proto proto
= {
188 .protocol_name
= "id-utils",
189 .protocol
= BACKEND_PROTO_ID_UTILS
,
190 .backend_proto_query
= idutils_query
,
191 .backend_proto_get
= idutils_backend_proto_get
,
192 .backend_proto_lookup
= idutils_backend_proto_lookup
,
193 .backend_proto_destory
= idutils_backend_proto_destory
,
194 .backend_proto_refresh
= idutils_backend_proto_refresh
,
197 backend_proto_register(&proto
);