1 /*
2  * s39ain.c  System39.ain read
3  *
4  * Copyright (C) 1997-1998 Masaki Chikama (Wren) <chikama@kasumi.ipl.mech.nagoya-u.ac.jp>
5  *               1998-                           <masaki-c@is.aist-nara.ac.jp>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21 */
22 /* $Id: s39ain.c,v 1.9 2003/07/21 23:06:47 chikama Exp $ */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <glib.h>
29 #include <ltdl.h>
30 
31 #include "portab.h"
32 #include "system.h"
33 #include "LittleEndian.h"
34 #include "nact.h"
35 #include "s39ain.h"
36 #include "xsystem35.h"
37 
38 /* short cut */
39 #define dll  nact->ain.dll
40 #define msg  nact->ain.msg
41 #define fnc  nact->ain.fnc
42 #define path_to_dll nact->ain.path_to_dll
43 #define path_to_ain nact->ain.path_to_ain
44 #define dllnum nact->ain.dllnum
45 #define fncnum nact->ain.fncnum
46 #define varnum nact->ain.varnum
47 #define msgnum nact->ain.msgnum
48 
49 /*
50   system39.ain ���ɤ߹���
51 */
s39ain_init(void)52 int s39ain_init(void) {
53 	FILE *fp;
54 	long len;
55 	char *buf;
56 	unsigned char *p;
57 	int i, errors = 0;
58 
59 	if (path_to_ain == NULL) {
60 		return NG;
61 	}
62 
63 	if (path_to_dll == NULL) {
64 		char path[512];
65 		getcwd(path, 400);
66 		strcat(path, "/modules");
67 		path_to_dll = strdup(path);
68 	}
69 
70 	if (NULL == (fp =  fopen(path_to_ain, "rb"))) {
71 		WARNING("fail to open %s\n", path_to_ain);
72 		return NG;
73 	}
74 
75 	fseek(fp, 0, SEEK_END);
76 	len = ftell(fp);
77 	fseek(fp, 0, SEEK_SET);
78 	buf = malloc(len + 4); /* +4 : VARI/MSGI... ��ĥ�Τ��� */
79 	fread(buf, 1, len, fp);
80 	fclose(fp);
81 
82 	p = buf;
83 	/* first check */
84 	if (0 != strncmp(p, "AINI", 4)) {
85 		WARNING("%s is not ain file\n", path_to_ain);
86 		free(buf);
87 		return NG;
88 	}
89 
90 	/* decode .ain file (thanx to Tajiri) */
91 	i = len -4;
92 	p = buf +4;
93 	for (; i > 0; i--) {
94 		unsigned char b = (*p) >> 6;
95 		unsigned char c = (*p) << 2;
96 		*p = b | c;
97 		p++;
98 	}
99 
100 	p = buf +8;
101 	if (0 != strncmp(p, "HEL0", 4)) {
102 		WARNING("%s is illigal ain file\n", path_to_ain);
103 		free(buf);
104 		return NG;
105 	}
106 	p += 8;
107 	dllnum = LittleEndian_getDW(p, 0);
108 	dll = g_new(S39AIN_DLLINF, dllnum);
109 
110 	p += 4;
111 	for (i = 0; i < dllnum; i++) {
112 		int fn, j;
113 
114 		dll[i].name = strdup(p); /* DLL name */
115 		p += strlen(p) + 1;
116 
117 		fn = LittleEndian_getDW(p, 0); /* number of function in DLL */
118 		p += 4;
119 
120 		dll[i].function_num = fn;
121 		dll[i].function = g_new(S39AIN_DLLFN, fn);
122 		for (j = 0; j < fn; j++) {
123 			int argc, k;
124 
125 			dll[i].function[j].name = strdup(p); /* function name */
126 			p += strlen(p) + 1;
127 
128 			argc = LittleEndian_getDW(p, 0); /* number of argument */
129 			p += 4;
130 
131 			dll[i].function[j].argc = argc;
132 			dll[i].function[j].argv = g_new(int, argc);
133 			for (k = 0; k < argc; k++) {
134 				dll[i].function[j].argv[k] = LittleEndian_getDW(p, 0);
135 				p += 4;
136 			}
137 		}
138 	}
139 
140 	/* check FUNC */
141 	if (0 == strncmp(p, "FUNC", 4)) {
142 		fncnum = LittleEndian_getDW(p, 8);
143 
144 		fnc = g_new(S39AIN_FUNCNAME, fncnum);
145 		p += 12;
146 
147 		for (i = 0; i < fncnum; i++) {
148 			fnc[i].name = strdup(p);
149 			p += strlen(p) + 1;
150 			fnc[i].page  = LittleEndian_getW(p, 0);
151 			fnc[i].index = LittleEndian_getDW(p, 2);
152 			p += 6;
153 		}
154 	}
155 
156 	/* check VARI */
157 	if (0 == strncmp(p, "VARI", 4)) {
158 		varnum = LittleEndian_getDW(p, 8);
159 		p += 12;
160 		for (i = 0; i < varnum; i++) {
161 			p += strlen(p) + 1;
162 		}
163 	}
164 
165 	/* check MSGI */
166 	if (0 == strncmp(p, "MSGI", 4)) {
167 		msgnum = LittleEndian_getDW(p, 8);
168 
169 		msg = g_new(char *, msgnum);
170 		p += 12;
171 
172 		for (i = 0; i < msgnum; i++) {
173 			msg[i] = strdup(p);
174 			p += strlen(p) + 1;
175 		}
176 	}
177 
178 	errors = lt_dlinit();
179 	if (errors) {
180 		printf("lt_dlinit fail\n");
181 		free(buf);
182 		return FALSE;
183 	}
184 
185 	/* open dll */
186 	for (i = 0; i < dllnum; i++) {
187 		char searchpath[512];
188 		void *handle;
189 
190 		if (dll[i].function_num == 0) continue;
191 
192 		// �ǽ�˥����ȥǥ��쥯�ȥ�Υ������ĥ꡼�β���
193 		// �⥸�塼�����
194 		g_snprintf(searchpath, sizeof(searchpath) -1, "%s/%s",
195 			   path_to_dll, dll[i].name);
196 
197 		lt_dlsetsearchpath(searchpath);
198 
199 		// ���˥ǥե���ȤΥ⥸�塼�����
200 		/* package default path, ex. /usr/local/lib/xsystem35/ */
201 		lt_dladdsearchdir(MODULE_PATH);
202 
203 		// fprintf(stderr, "try to open %s/%s\n", searchpath, dll[i].name);
204 		handle = lt_dlopenext(dll[i].name);
205 
206 		if (handle == NULL) {
207 			SYSERROR("dlopen: %s(%s)\n", lt_dlerror(), dll[i].name);
208 		}
209 
210 		dll[i].handle = handle;
211 	}
212 
213 	free(buf);
214 	return OK;
215 }
216