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