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