1 /**************************************************************************/
2 /* ---------------------------------------------------------------------- */
3 /* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
5 /* Universidad de Cantabria, SPAIN */
6 /* University of York, UK */
7 /* Scuola Superiore Sant'Anna, ITALY */
8 /* Kaiserslautern University, GERMANY */
9 /* Univ. Politécnica Valencia, SPAIN */
10 /* Czech Technical University in Prague, CZECH REPUBLIC */
12 /* Thales Communication S.A. FRANCE */
13 /* Visual Tools S.A. SPAIN */
14 /* Rapita Systems Ltd UK */
17 /* See http://www.frescor.org for a link to partners' websites */
19 /* FRESCOR project (FP6/2005/IST/5-034026) is funded */
20 /* in part by the European Union Sixth Framework Programme */
21 /* The European Union is not liable of any use that may be */
22 /* made of this code. */
25 /* This file is part of FORB (Frescor Object Request Broker) */
27 /* FORB is free software; you can redistribute it and/or modify it */
28 /* under terms of the GNU General Public License as published by the */
29 /* Free Software Foundation; either version 2, or (at your option) any */
30 /* later version. FORB is distributed in the hope that it will be */
31 /* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
32 /* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
33 /* General Public License for more details. You should have received a */
34 /* copy of the GNU General Public License along with FORB; see file */
35 /* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
36 /* Cambridge, MA 02139, USA. */
38 /* As a special exception, including FORB header files in a file, */
39 /* instantiating FORB generics or templates, or linking other files */
40 /* with FORB objects to produce an executable application, does not */
41 /* by itself cause the resulting executable application to be covered */
42 /* by the GNU General Public License. This exception does not */
43 /* however invalidate any other reasons why the executable file might be */
44 /* covered by the GNU Public License. */
45 /**************************************************************************/
53 #include <forb/config.h>
55 extern UL_LOG_CUST(ulogd_forb_regref);
57 static inline int forb_regref_cmp(const forb_regref_name_t *a, const forb_regref_name_t *b)
59 return strncmp(a->str, b->str, FORB_REGREF_NAME_LEN);
62 GAVL_CUST_NODE_INT_IMP(forb_regref_nolock /* cust_prefix */,
63 forb_t /* cust_root_t */,
64 forb_regref_t /* cust_item_t */,
65 forb_regref_name_t /* cust_key_t */,
66 regrefs /* cust_root_node */,
67 node /* cust_item_node */,
68 name /* cust_item_key */,
69 forb_regref_cmp/* cust_cmp_fnc */);
72 * Allocates a new ::forb_regref_t structure and fills it with data.
74 * @param object Object reference to register.
76 * @param name Name of the registered object reference, which can be
77 * used by other applications in forb_resolve_reference().
79 * @return Pointer to the newly allocated regref of NULL in case of error.
82 forb_regref_new(forb_object object, forb_regref_name_t name)
84 forb_regref_t *regref;
86 regref = forb_malloc(sizeof(*regref));
89 regref->object = forb_object_duplicate(object);
95 * Releases ::forb_regref_t previously allocated by forb_regref_new().
97 * @param regref Regref to release.
100 forb_regref_release(forb_regref_t *regref)
103 forb_object_release(regref->object);
110 #ifndef CONFIG_FORB_PROTO_INET_DEFAULT
117 * @return Zero on success, -1 on error.
120 rewrite_regref(int fd, const char *objref)
123 int len = strlen(objref);
124 lseek(fd, 0, SEEK_SET);
128 ret = write(fd, objref, len);
129 if (ret < 0) goto out;
133 ret = 0; /* Success */
142 * @param fn File name
143 * @param objref string form of the object reference
145 * @return -1 on error, 0 if reference was replaced and 1 in the
146 * reference is valid.
149 replace_regref_if_stale(forb_orb orb, const char *fn, const char *objref)
155 fd = open(fn, O_RDWR);
160 ret = lockf(fd, F_LOCK, 0);
161 if (ret < 0) goto close_err;
162 ret = read(fd, str, sizeof(str)-1);
163 if (ret < 0) goto unlock_err;
164 /* TODO: Check that we have read the whole file */
167 object = forb_string_to_object(orb, str);
169 /* reference is unreadable, so we can replace it */
170 ret = rewrite_regref(fd, objref);
171 /* We are done for now */
174 if (forb_object_is_stale(object)) {
175 /* Orb is not alive */
176 ret = rewrite_regref(fd, objref);
178 /* Reference's FORB is alive :-( */
182 forb_object_release(object);
184 lockf(fd, F_ULOCK, 0);
193 * Registers a given object reference so that other FORBs on the same
194 * node can find it by using forb_resolve_reference().
196 * @param object Object reference to register.
197 * @param name Name under which to register the reference.
199 * @return Zero on success, -1 on error.
202 forb_register_reference(forb_object object, const char *name)
204 forb_regref_t *regref;
205 forb_regref_name_t regname;
206 forb_t *forb = forb_object_to_forb(object);
208 strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
209 regname.str[FORB_REGREF_NAME_LEN-1]='\0';
211 regref = forb_regref_new(object, regname);
212 if (!regref) goto err;
214 forb_regref_insert(forb, regref);
216 #ifdef CONFIG_FORB_PROTO_INET_DEFAULT
219 char fn[100], fntmp[100];
223 snprintf(fn, sizeof(fn), FORB_TMP_DIR "/%s", regname.str);
224 snprintf(fntmp, sizeof(fntmp), FORB_TMP_DIR "/%s.%s", regname.str,
225 forb->server_id_str);
227 f = fopen(fntmp, "w");
228 if (!f) goto unalloc_err;
230 objref = forb_object_to_string(object);
231 if (!objref) goto unlink_err;
233 ret = fprintf(f, "%s", objref);
234 if (ret < 0) goto free_objref_err;
237 if (ret == EOF) goto free_objref_err;
239 /* Make the atomic registration in filesystem */
240 ret = link(fntmp, fn);
242 if (ret < 0 && errno == EEXIST) {
243 /* The reference exists. Try whether it is still
245 if (replace_regref_if_stale(object->orb, fn, objref) != 0) {
246 goto free_objref_err;
248 ul_logdeb("Stale registration replaced\n");
249 } else if (ret < 0) {
250 goto free_objref_err;
255 /* Unlink the temporary filename */
269 forb_regref_delete(forb, regref);
270 forb_regref_release(regref);
278 * Unregister reference previously registered by
279 * forb_register_reference().
281 * @param orb forb::orb reference
282 * @param name Name to unregister.
284 * @return Zero on success, -1 on error.
287 forb_unregister_reference(forb_orb orb, const char *name)
289 forb_regref_t *regref;
290 forb_regref_name_t regname;
291 forb_t *forb = forb_object_to_forb(orb);
293 strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
294 regname.str[FORB_REGREF_NAME_LEN-1]='\0';
296 regref = forb_regref_find(forb, ®name);
297 if (!regref) goto err;
299 forb_regref_delete(forb, regref);
300 forb_regref_release(regref);
302 #ifndef CONFIG_FORB_PROTO_INET_DEFAULT
304 snprintf(fn, sizeof(fn), FORB_TMP_DIR "/%s", regname.str);
314 * Returns a named reference previously registered by
315 * forb_register_reference(). This function can be called even if the
316 * reference was registered in a diferent process (but on the same
319 * @param orb Local orb object reference
320 * @param name Name under which the reference was registered.
322 * @return Object reference on NULL in case of error.
325 forb_resolve_reference(const forb_orb orb, const char *name)
327 forb_regref_name_t regname;
330 strncpy(regname.str, name, FORB_REGREF_NAME_LEN-1);
331 regname.str[FORB_REGREF_NAME_LEN-1]='\0';
333 #ifdef CONFIG_FORB_PROTO_INET_DEFAULT
334 forb_regref_t *regref;
335 forb_t *forb = forb_object_to_forb(orb);
337 regref = forb_regref_find(forb, ®name);
338 if (!regref) return NULL;
340 object = forb_object_duplicate(regref->object);
348 snprintf(fn, sizeof(fn), FORB_TMP_DIR "/%s", regname.str);
354 ret = read(fd, str, sizeof(str)-1);
355 /* TODO: Check that we have read the whole file */
357 object = forb_string_to_object(orb, str);
361 if (forb_object_is_stale(object)) {
362 forb_object_release(object);