1 /*
2 * gmodules.c -- gpart module functions
3 *
4 * gpart (c) 1999-2001 Michail Brzitwa <mb@ichabod.han.de>
5 * Guess PC-type hard disk partitions.
6 *
7 * gpart is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; either version 2, or (at your
10 * option) any later version.
11 *
12 * Created: 04.01.1999 <mb@ichabod.han.de>
13 * Modified: 29.01.2001 <mb@ichabod.han.de>
14 * New modules: qnx & beos.
15 *
16 */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <dlfcn.h>
22 #include "gpart.h"
23
24
25 static g_module *g_head;
26 static int g_count;
27
28
29
g_mod_head()30 g_module *g_mod_head()
31 {
32 return (g_head);
33 }
34
35
36
g_mod_count()37 int g_mod_count()
38 {
39 return (g_count);
40 }
41
42
43
g_mod_list()44 void g_mod_list()
45 {
46 g_module *m;
47
48 pr(MSG,"Module\tWeight\n");
49 for (m = g_head; m; m = m->m_next)
50 pr(MSG,"%s\t(%3.1f)\n",m->m_name,m->m_weight);
51 pr(MSG,"\n");
52 }
53
54
55
g_mod_delete(g_module * m)56 void g_mod_delete(g_module *m)
57 {
58 if (m)
59 {
60 if (m->m_hd) dlclose(m->m_hd);
61 if (m->m_name) free((void *)m->m_name);
62 free(m);
63 g_count--;
64 }
65 }
66
67
68
g_mod_deleteall()69 void g_mod_deleteall()
70 {
71 g_module *m;
72
73 while (g_head)
74 {
75 m = g_head->m_next; g_mod_delete(g_head); g_head = m;
76 }
77 }
78
79
80
81 /*
82 * set weight of module and re-insert as head.
83 */
84
g_mod_setweight(char * name,float weight)85 g_module *g_mod_setweight(char *name,float weight)
86 {
87 g_module *m, *prev = 0;
88
89 for (m = g_head; m; m = m->m_next)
90 if (strcmp(m->m_name,name) == 0)
91 break;
92 else
93 prev = m;
94 if (m == 0)
95 return (0);
96 if (prev)
97 {
98 prev->m_next = m->m_next;
99 m->m_next = g_head;
100 g_head = m;
101 }
102 g_head->m_weight = weight;
103 return (g_head);
104 }
105
106
107
g_mod_lookup(int how,char * name)108 g_module *g_mod_lookup(int how,char *name)
109 {
110 g_module *m;
111
112 if (g_head == 0)
113 {
114 if (how == GM_LOOKUP)
115 return (0);
116 g_head = (g_module *)alloc(sizeof(g_module));
117 m = g_head;
118 }
119 else
120 {
121 for (m = g_head; m->m_next; m = m->m_next)
122 if (strcmp(m->m_name,name) == 0)
123 return (m);
124 if (how == GM_LOOKUP)
125 return (0);
126 m->m_next = (g_module *)alloc(sizeof(g_module));
127 m = m->m_next;
128 }
129 if ((m->m_name = strdup(name)) == 0)
130 pr(FATAL,"out of memory in strdup");
131 m->m_weight = 1.0; g_count++;
132 return (m);
133 }
134
135
136
137 /*
138 * preloaded modules
139 */
140
g_mod_addinternals()141 void g_mod_addinternals()
142 {
143 g_module *m;
144
145 #define GMODINS(mod) if(!(m = g_mod_lookup(GM_INSERT,#mod))->m_hd){ \
146 m->m_init=mod##_init; m->m_term=mod##_term; \
147 m->m_gfun=mod##_gfun; }
148
149 /*
150 * If no weights are given on the command line, the order
151 * is somehow important.
152 */
153
154 GMODINS(bsddl);
155 GMODINS(lswap);
156 GMODINS(qnx4);
157 GMODINS(rfs);
158 GMODINS(ntfs);
159 GMODINS(hpfs);
160 GMODINS(minix);
161 GMODINS(beos);
162 GMODINS(ext2);
163 GMODINS(fat);
164 GMODINS(s86dl);
165 GMODINS(hmlvm);
166 GMODINS(xfs);
167 }
168
169
170
g_mod_addexternal(char * name)171 int g_mod_addexternal(char *name)
172 {
173 g_module *m;
174 char buf[FILENAME_MAX];
175
176 /*
177 * external modules are named 'gm_' name '.so', and will
178 * be searched in the standard ld.so library directories
179 * or those explicitly given by LD_LIBRARY_PATH.
180 */
181
182 snprintf(buf,FILENAME_MAX-1,"gm_%s.so",name);
183 buf[FILENAME_MAX-1] = 0;
184
185 m = g_mod_lookup(GM_INSERT,name);
186 if (m->m_hd)
187 dlclose(m->m_hd);
188
189 if ((m->m_hd = dlopen(buf,RTLD_NOW)) == 0)
190 pr(FATAL,(char *)dlerror());
191
192 snprintf(buf,FILENAME_MAX-1,"%s_init",name);
193 m->m_init = (int (*)())dlsym(m->m_hd,buf);
194 snprintf(buf,FILENAME_MAX-1,"%s_term",name);
195 m->m_term = (int (*)())dlsym(m->m_hd,buf);
196 snprintf(buf,FILENAME_MAX-1,"%s_gfun",name);
197 m->m_gfun = (int (*)())dlsym(m->m_hd,buf);
198 if ((m->m_gfun == 0))
199 pr(FATAL,"module %s: missing vital functions",name);
200
201 return (1);
202 }
203