captive_options module-loading generalized to be CORBA transportable
[captive.git] / src / libcaptive / client / options-module.c
1 /* $Id$
2  * User options handling code of libcaptive
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "captive/options.h"    /* self */
23 #include <glib/gmessages.h>
24 #include "captive/macros.h"
25 #include <glib/gstrfuncs.h>
26 #include <stdlib.h>
27 #include "captive/rtl-file.h"
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31 #include <sys/mman.h>
32
33
34 gboolean captive_options_module_load(struct captive_options_module *options_module,const gchar *pathname_utf8)
35 {
36         g_return_val_if_fail(options_module!=NULL,FALSE);
37         g_return_val_if_fail(pathname_utf8!=NULL,FALSE);
38
39         /* Open the Module */
40         options_module->type=CAPTIVE_OPTIONS_MODULE_TYPE_PE32;
41         options_module->pathname_utf8=g_strdup(pathname_utf8);
42         options_module->u.pe32.mapped=TRUE;
43         options_module->u.pe32.base=captive_rtl_file_mmap(
44                         &options_module->u.pe32.length, /* lenp */
45                         pathname_utf8,  /* path */
46                         O_RDONLY,       /* open_flags */
47                         PROT_READ,      /* mmap_prot */
48                         MAP_SHARED);    /* mmap_flags */
49         /* FIXME: convert errno instead of STATUS_INSUFFICIENT_RESOURCES */
50         g_return_val_if_fail(options_module->u.pe32.base!=NULL,FALSE);
51
52         if (options_module->u.pe32.length>=2
53                         && (('M'<<8U)|('Z'<<0U))==GUINT16_FROM_BE(*(const guint16 *)options_module->u.pe32.base)) {
54                 /* already done above */
55                 }
56         else {
57                 captive_rtl_file_munmap(options_module->u.pe32.base);
58                 options_module->type=CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE;
59                 options_module->u.gmodule.pathname=g_strdup(pathname_utf8);
60                 }
61
62         return TRUE;
63 }
64
65
66 void captive_options_module_copy(struct captive_options_module *dest,const struct captive_options_module *src)
67 {
68         g_return_if_fail(dest!=NULL);
69         g_return_if_fail(src!=NULL);
70
71         dest->pathname_utf8=g_strdup(src->pathname_utf8);
72
73         dest->type=src->type;
74         switch (src->type) {
75                 case CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY: g_assert_not_reached();
76
77                 case CAPTIVE_OPTIONS_MODULE_TYPE_PE32:
78                         dest->u.pe32.base=g_memdup(src->u.pe32.base,src->u.pe32.length);
79                         dest->u.pe32.length=src->u.pe32.length;
80                         dest->u.pe32.mapped=FALSE;
81                         break;
82
83                 case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE:
84                         dest->u.gmodule.pathname=g_strdup(src->u.gmodule.pathname);
85                         break;
86
87                 default: g_assert_not_reached();
88                 }
89 }
90
91
92 void captive_options_module_free(struct captive_options_module *options_module)
93 {
94         g_return_if_fail(options_module!=NULL);
95
96         g_free(options_module->pathname_utf8);
97
98         switch (options_module->type) {
99                 case CAPTIVE_OPTIONS_MODULE_TYPE_EMPTY:
100                         break;
101
102                 case CAPTIVE_OPTIONS_MODULE_TYPE_PE32:
103                         if (options_module->u.pe32.mapped)
104                                 captive_rtl_file_munmap(options_module->u.pe32.base);
105                         else
106                                 g_free(options_module->u.pe32.base);
107                         break;
108
109                 case CAPTIVE_OPTIONS_MODULE_TYPE_GMODULE:
110                         g_free(options_module->u.gmodule.pathname);
111                         break;
112
113                 default: g_assert_not_reached();
114                 }
115 }