Subversion Repositories SvarDOS

Rev

Rev 608 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 608 Rev 611
1
/*
1
/*
2
 * functions that reads/writes from/to the localcfg country.sys-like file.
2
 * functions that reads/writes from/to the localcfg country.sys-like file.
3
 * Copyright (C) Mateusz Viste 2015-2022
3
 * Copyright (C) Mateusz Viste 2015-2022
4
 */
4
 */
5
 
5
 
6
#include <stdio.h>
6
#include <stdio.h>
7
#include <string.h>
7
#include <string.h>
8
 
8
 
9
#include "country.h"
9
#include "country.h"
10
 
10
 
11
 
11
 
12
struct funchdr {
12
struct funchdr {
13
  unsigned char funcname[8];
13
  unsigned char funcname[8];
14
  unsigned short funcsiz;
14
  unsigned short funcsiz;
15
};
15
};
16
 
16
 
17
static unsigned char filebuff[1024];
17
static unsigned char filebuff[1024];
18
 
18
 
19
 
19
 
20
/* fills a country struct with default values */
20
/* fills a country struct with default values */
21
static void country_default(struct country *countrydata) {
21
static void country_default(struct country *countrydata) {
22
 
22
 
23
  /* first clear the memory */
23
  /* first clear the memory */
24
  bzero(countrydata, sizeof(struct country));
24
  bzero(countrydata, sizeof(struct country));
25
 
25
 
26
  /* fill in CTYINFO fields (non-zero values only) */
26
  /* fill in CTYINFO fields (non-zero values only) */
27
  countrydata->CTYINFO.id = 1;
27
  countrydata->CTYINFO.id = 1;
28
  countrydata->CTYINFO.codepage = 437;
28
  countrydata->CTYINFO.codepage = 437;
29
  /* countrydata->CTYINFO.datefmt = COUNTRY_DATE_MDY;
29
  /* countrydata->CTYINFO.datefmt = COUNTRY_DATE_MDY;
30
  countrydata->CTYINFO.timefmt = COUNTRY_TIME12; */
30
  countrydata->CTYINFO.timefmt = COUNTRY_TIME12; */
31
  countrydata->CTYINFO.currsym[0] = '$';
31
  countrydata->CTYINFO.currsym[0] = '$';
32
  countrydata->CTYINFO.decimal[0] = '.';
32
  countrydata->CTYINFO.decimal[0] = '.';
33
  countrydata->CTYINFO.thousands[0] = ',';
33
  countrydata->CTYINFO.thousands[0] = ',';
34
  countrydata->CTYINFO.datesep[0] = '/';
34
  countrydata->CTYINFO.datesep[0] = '/';
35
  countrydata->CTYINFO.timesep[0] = ':';
35
  countrydata->CTYINFO.timesep[0] = ':';
36
  countrydata->CTYINFO.currprec = 2;
36
  countrydata->CTYINFO.currprec = 2;
37
  /* countrydata->CTYINFO.currencydecsym = 0; */
37
  /* countrydata->CTYINFO.currencydecsym = 0; */
38
  /* countrydata->CTYINFO.currencyspace = 0; */
38
  /* countrydata->CTYINFO.currencyspace = 0; */
39
  /* countrydata->CTYINFO.currencypos = 0; */
39
  /* countrydata->CTYINFO.currencypos = 0; */
40
 
40
 
41
  /* fill in YESNO fields (non-zero values only) */
41
  /* fill in YESNO fields (non-zero values only) */
42
  countrydata->YESNO.yes[0] = 'Y';
42
  countrydata->YESNO.yes[0] = 'Y';
43
  countrydata->YESNO.no[0] = 'N';
43
  countrydata->YESNO.no[0] = 'N';
44
}
44
}
45
 
45
 
46
 
46
 
47
/* Loads data from a country.sys file into a country struct.
47
/* Loads data from a country.sys file into a country struct.
48
 * Returns 0 on success, non-zero otherwise. */
48
 * Returns 0 on success, non-zero otherwise. */
49
int country_read(struct country *countrydata, const char *fname) {
49
int country_read(struct country *countrydata, const char *fname) {
50
  short firstentryoffs;
50
  short firstentryoffs;
51
  unsigned char *subfunctions[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
51
  unsigned char *subfunctions[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
52
                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
52
                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
53
  short filesize;
53
  short filesize;
54
  short subfunctionscount;
54
  short subfunctionscount;
55
  unsigned char *functiondata;
55
  unsigned char *functiondata;
56
  int x;
56
  int x;
57
  FILE *fd;
57
  FILE *fd;
58
 
58
 
59
  /* preload the country struct with default values */
59
  /* preload the country struct with default values */
60
  country_default(countrydata);
60
  country_default(countrydata);
61
 
61
 
62
  /* load the file into buff, if file exists */
62
  /* load the file into buff, if file exists */
63
  fd = fopen(fname, "rb");
63
  fd = fopen(fname, "rb");
64
  if (fd == NULL) return(0); /* "file doesn't exist" is not an error condition */
64
  if (fd == NULL) return(0); /* "file doesn't exist" is not an error condition */
65
  filesize = fread(filebuff, 1, sizeof(filebuff), fd);
65
  filesize = fread(filebuff, 1, sizeof(filebuff), fd);
66
  fclose(fd);
66
  fclose(fd);
67
 
67
 
68
  /* check that it's a country file - should start with 0xFF COUNTRY 0x00 */
68
  /* check that it's a country file - should start with 0xFF COUNTRY 0x00 */
69
  if (memcmp(filebuff, "\377COUNTRY\0", 9) != 0) return(-2);
69
  if (memcmp(filebuff, "\377COUNTRY\0", 9) != 0) return(COUNTRY_ERR_INV_FORMAT);
70
 
70
 
71
  /* check that it's one of my country.sys files - should contain a trailer */
71
  /* check that it's one of my country.sys files - should contain a trailer */
72
  if (memcmp(filebuff + filesize - 8, "LOCALCFG", 8) != 0) return(-3);
72
  if (memcmp(filebuff + filesize - 8, "LOCALCFG", 8) != 0) return(COUNTRY_ERR_NOT_LOCALCFG);
73
 
73
 
74
  /* read the offset of the entries index - must be at least 23 */
74
  /* read the offset of the entries index - must be at least 23 */
75
  functiondata = filebuff + 19;
75
  functiondata = filebuff + 19;
76
  firstentryoffs = *((unsigned short *)functiondata);
76
  firstentryoffs = *((unsigned short *)functiondata);
77
  if ((firstentryoffs < 23) || (firstentryoffs >= filesize)) return(-4);
77
  if ((firstentryoffs < 23) || (firstentryoffs >= filesize)) return(-4);
78
  functiondata = filebuff + firstentryoffs;
78
  functiondata = filebuff + firstentryoffs;
79
 
79
 
80
  /* how many entries do we have? I expect exactly one. */
80
  /* how many entries do we have? I expect exactly one. */
81
  if (*((unsigned short *)functiondata) != 1) return(-5);
81
  if (*((unsigned short *)functiondata) != 1) return(-5);
82
  /* skip to the first country entry */
82
  /* skip to the first country entry */
83
  functiondata += 2;
83
  functiondata += 2;
84
 
84
 
85
  /* skip directly to the subfunctions of the first country */
85
  /* skip directly to the subfunctions of the first country */
86
  /* ddwords: size, country, codepage, reserved, reserved, offset */
86
  /* ddwords: size, country, codepage, reserved, reserved, offset */
87
  /* printf("Size = %d\n", READSHORT(functiondata)); */
87
  /* printf("Size = %d\n", READSHORT(functiondata)); */
88
  functiondata += 2; /* skip size */
88
  functiondata += 2; /* skip size */
89
  /* printf("Country = %d\n", READSHORT(functiondata[0]); */
89
  /* printf("Country = %d\n", READSHORT(functiondata[0]); */
90
  functiondata += 2; /* skip country */
90
  functiondata += 2; /* skip country */
91
  /* printf("Codepage = %d\n", READSHORT(functiondata)); */
91
  /* printf("Codepage = %d\n", READSHORT(functiondata)); */
92
  functiondata += 2; /* skip codepage */
92
  functiondata += 2; /* skip codepage */
93
  functiondata += 4; /* skip reserved fields */
93
  functiondata += 4; /* skip reserved fields */
94
  firstentryoffs = *((unsigned short *)functiondata); /* read offset of the subfunctions index */
94
  firstentryoffs = *((unsigned short *)functiondata); /* read offset of the subfunctions index */
95
  functiondata = filebuff + firstentryoffs;
95
  functiondata = filebuff + firstentryoffs;
96
 
96
 
97
  /* read all subfunctions, but no more than 15 */
97
  /* read all subfunctions, but no more than 15 */
98
  subfunctionscount = *((unsigned short *)functiondata);
98
  subfunctionscount = *((unsigned short *)functiondata);
99
  /* printf("Found %d subfunctions\n", subfunctionscount); */
99
  /* printf("Found %d subfunctions\n", subfunctionscount); */
100
  functiondata += 2;
100
  functiondata += 2;
101
  for (x = 0; (x < 15) && (x < subfunctionscount); x++) {
101
  for (x = 0; (x < 15) && (x < subfunctionscount); x++) {
102
    short size = *((unsigned short *)functiondata);
102
    short size = *((unsigned short *)functiondata);
103
    functiondata += 2;
103
    functiondata += 2;
104
    functiondata += 2; /* skip ID of the subfunction */
104
    functiondata += 2; /* skip ID of the subfunction */
105
    subfunctions[x] = filebuff + *((unsigned short *)functiondata);
105
    subfunctions[x] = filebuff + *((unsigned short *)functiondata);
106
    /* printf("subfunction %d at 0x%p\n", x, subfunctions[x]); */
106
    /* printf("subfunction %d at 0x%p\n", x, subfunctions[x]); */
107
    functiondata += size - 2;
107
    functiondata += size - 2;
108
  }
108
  }
109
 
109
 
110
  /* load every subfunction, and feed the country struct with data */
110
  /* load every subfunction, and feed the country struct with data */
111
  for (x = 0; subfunctions[x] != NULL; x++) {
111
  for (x = 0; subfunctions[x] != NULL; x++) {
112
    struct funchdr *hdr = (void *)(subfunctions[x]);
112
    struct funchdr *hdr = (void *)(subfunctions[x]);
113
    functiondata = subfunctions[x] + 10;
113
    functiondata = subfunctions[x] + 10;
114
    /* */
114
    /* */
115
    if ((memcmp(hdr->funcname, "\377YESNO  ", 8) == 0) && (hdr->funcsiz == 4)) {
115
    if ((memcmp(hdr->funcname, "\377YESNO  ", 8) == 0) && (hdr->funcsiz == 4)) {
116
      memcpy(&(countrydata->YESNO), functiondata, hdr->funcsiz);
116
      memcpy(&(countrydata->YESNO), functiondata, hdr->funcsiz);
117
    } else if ((memcmp(hdr->funcname, "\377CTYINFO", 8) == 0) && (hdr->funcsiz == 22)) {
117
    } else if ((memcmp(hdr->funcname, "\377CTYINFO", 8) == 0) && (hdr->funcsiz == 22)) {
118
      memcpy(&(countrydata->CTYINFO), functiondata, hdr->funcsiz);
118
      memcpy(&(countrydata->CTYINFO), functiondata, hdr->funcsiz);
119
    }
119
    }
120
  }
120
  }
121
 
121
 
122
  return(0);
122
  return(0);
123
}
123
}
124
 
124
 
125
 
125
 
126
#define MSB(x) (((x) >> 8) & 0xff)
126
#define MSB(x) (((x) >> 8) & 0xff)
127
#define LSB(x) ((x) & 0xff)
127
#define LSB(x) ((x) & 0xff)
128
 
128
 
129
 
129
 
130
/* Computes a new country.sys file based on data from a country struct.
130
/* Computes a new country.sys file based on data from a country struct.
131
 * Returns 0 on success, non-zero otherwise. */
131
 * Returns 0 on success, non-zero otherwise. */
132
int country_write(const char *fname, struct country *c) {
132
int country_write(const char *fname, struct country *c) {
133
  short filesize = 0;
133
  short filesize = 0;
134
  FILE *fd;
134
  FILE *fd;
135
  int x;
135
  int x;
136
  short subfunction_id[7] = {1,2,4,5,6,7,35};
136
  short subfunction_id[7] = {1,2,4,5,6,7,35};
137
  short subfunction_ptr[7];
137
  short subfunction_ptr[7];
138
 
138
 
139
  const unsigned char ucase_437[128] = {128, 154,  69,  65, 142,  65, 143, 128,
139
  const unsigned char ucase_437[128] = {128, 154,  69,  65, 142,  65, 143, 128,
140
                                         69,  69,  69,  73,  73,  73, 142, 143,
140
                                         69,  69,  69,  73,  73,  73, 142, 143,
141
                                        144, 146, 146,  79, 153,  79,  85,  85,
141
                                        144, 146, 146,  79, 153,  79,  85,  85,
142
                                         89, 153, 154, 155, 156, 157, 158, 159,
142
                                         89, 153, 154, 155, 156, 157, 158, 159,
143
                                         65,  73,  79,  85, 165, 165, 166, 167,
143
                                         65,  73,  79,  85, 165, 165, 166, 167,
144
                                        168, 169, 170, 171, 172, 173, 174, 175,
144
                                        168, 169, 170, 171, 172, 173, 174, 175,
145
                                        176, 177, 178, 179, 180, 181, 182, 183,
145
                                        176, 177, 178, 179, 180, 181, 182, 183,
146
                                        184, 185, 186, 187, 188, 189, 190, 191,
146
                                        184, 185, 186, 187, 188, 189, 190, 191,
147
                                        192, 193, 194, 195, 196, 197, 198, 199,
147
                                        192, 193, 194, 195, 196, 197, 198, 199,
148
                                        200, 201, 202, 203, 204, 205, 206, 207,
148
                                        200, 201, 202, 203, 204, 205, 206, 207,
149
                                        208, 209, 210, 211, 212, 213, 214, 215,
149
                                        208, 209, 210, 211, 212, 213, 214, 215,
150
                                        216, 217, 218, 219, 220, 221, 222, 223,
150
                                        216, 217, 218, 219, 220, 221, 222, 223,
151
                                        224, 225, 226, 227, 228, 229, 230, 231,
151
                                        224, 225, 226, 227, 228, 229, 230, 231,
152
                                        232, 233, 234, 235, 236, 237, 238, 239,
152
                                        232, 233, 234, 235, 236, 237, 238, 239,
153
                                        240, 241, 242, 243, 244, 245, 246, 247,
153
                                        240, 241, 242, 243, 244, 245, 246, 247,
154
                                        248, 249, 250, 251, 252, 253, 254, 255};
154
                                        248, 249, 250, 251, 252, 253, 254, 255};
155
 
155
 
156
  const unsigned char collate_437[256] = {  0,   1,   2,   3,   4,   5,   6,   7,
156
  const unsigned char collate_437[256] = {  0,   1,   2,   3,   4,   5,   6,   7,
157
                                            8,   9,  10,  11,  12,  13,  14,  15,
157
                                            8,   9,  10,  11,  12,  13,  14,  15,
158
                                           16,  17,  18,  19,  20,  21,  22,  23,
158
                                           16,  17,  18,  19,  20,  21,  22,  23,
159
                                           24,  25,  26,  27,  28,  29,  30,  31,
159
                                           24,  25,  26,  27,  28,  29,  30,  31,
160
                                           32,  33,  34,  35,  36,  37,  38,  39,
160
                                           32,  33,  34,  35,  36,  37,  38,  39,
161
                                           40,  41,  42,  43,  44,  45,  46,  47,
161
                                           40,  41,  42,  43,  44,  45,  46,  47,
162
                                           48,  49,  50,  51,  52,  53,  54,  55,
162
                                           48,  49,  50,  51,  52,  53,  54,  55,
163
                                           56,  57,  58,  59,  60,  61,  62,  63,
163
                                           56,  57,  58,  59,  60,  61,  62,  63,
164
                                           64,  65,  66,  67,  68,  69,  70,  71,
164
                                           64,  65,  66,  67,  68,  69,  70,  71,
165
                                           72,  73,  74,  75,  76,  77,  78,  79,
165
                                           72,  73,  74,  75,  76,  77,  78,  79,
166
                                           80,  81,  82,  83,  84,  85,  86,  87,
166
                                           80,  81,  82,  83,  84,  85,  86,  87,
167
                                           88,  89,  90,  91,  92,  93,  94,  95,
167
                                           88,  89,  90,  91,  92,  93,  94,  95,
168
                                           96,  65,  66,  67,  68,  69,  70,  71,
168
                                           96,  65,  66,  67,  68,  69,  70,  71,
169
                                           72,  73,  74,  75,  76,  77,  78,  79,
169
                                           72,  73,  74,  75,  76,  77,  78,  79,
170
                                           80,  81,  82,  83,  84,  85,  86,  87,
170
                                           80,  81,  82,  83,  84,  85,  86,  87,
171
                                           88,  89,  90, 123, 124, 125, 126, 127,
171
                                           88,  89,  90, 123, 124, 125, 126, 127,
172
                                           67,  85,  69,  65,  65,  65,  65,  67,
172
                                           67,  85,  69,  65,  65,  65,  65,  67,
173
                                           69,  69,  69,  73,  73,  73,  65,  65,
173
                                           69,  69,  69,  73,  73,  73,  65,  65,
174
                                           69,  65,  65,  79,  79,  79,  85,  85,
174
                                           69,  65,  65,  79,  79,  79,  85,  85,
175
                                           89,  79,  85,  36,  36,  36,  36,  36,
175
                                           89,  79,  85,  36,  36,  36,  36,  36,
176
                                           65,  73,  79,  85,  78,  78, 166, 167,
176
                                           65,  73,  79,  85,  78,  78, 166, 167,
177
                                           63, 169, 170, 171, 172,  33,  34,  34,
177
                                           63, 169, 170, 171, 172,  33,  34,  34,
178
                                          176, 177, 178, 179, 180, 181, 182, 183,
178
                                          176, 177, 178, 179, 180, 181, 182, 183,
179
                                          184, 185, 186, 187, 188, 189, 190, 191,
179
                                          184, 185, 186, 187, 188, 189, 190, 191,
180
                                          192, 193, 194, 195, 196, 197, 198, 199,
180
                                          192, 193, 194, 195, 196, 197, 198, 199,
181
                                          200, 201, 202, 203, 204, 205, 206, 207,
181
                                          200, 201, 202, 203, 204, 205, 206, 207,
182
                                          208, 209, 210, 211, 212, 213, 214, 215,
182
                                          208, 209, 210, 211, 212, 213, 214, 215,
183
                                          216, 217, 218, 219, 220, 221, 222, 223,
183
                                          216, 217, 218, 219, 220, 221, 222, 223,
184
                                          224,  83, 226, 227, 228, 229, 230, 231,
184
                                          224,  83, 226, 227, 228, 229, 230, 231,
185
                                          232, 233, 234, 235, 236, 237, 238, 239,
185
                                          232, 233, 234, 235, 236, 237, 238, 239,
186
                                          240, 241, 242, 243, 244, 245, 246, 247,
186
                                          240, 241, 242, 243, 244, 245, 246, 247,
187
                                          248, 249, 250, 251, 252, 253, 254, 255};
187
                                          248, 249, 250, 251, 252, 253, 254, 255};
188
 
188
 
189
  /* zero out filebuff */
189
  /* zero out filebuff */
190
  bzero(filebuff, sizeof(filebuff));
190
  bzero(filebuff, sizeof(filebuff));
191
 
191
 
192
  /* compute the country.sys structures */
192
  /* compute the country.sys structures */
193
  memcpy(filebuff, "\377COUNTRY\0\0\0\0\0\0\0\0\1\0\1", 19); /* header */
193
  memcpy(filebuff, "\377COUNTRY\0\0\0\0\0\0\0\0\1\0\1", 19); /* header */
194
  filesize = 19;
194
  filesize = 19;
195
  /* first entry offset (always current offset+4) */
195
  /* first entry offset (always current offset+4) */
196
  filesize += 4;
196
  filesize += 4;
197
  memcpy(filebuff + filesize - 4, &filesize, sizeof(filesize));
197
  memcpy(filebuff + filesize - 4, &filesize, sizeof(filesize));
198
  /* number of entries */
198
  /* number of entries */
199
  filebuff[filesize] = 1;
199
  filebuff[filesize] = 1;
200
  filesize += 2;
200
  filesize += 2;
201
  /* first (and only) entry / size, country, codepage, reserved(2), offset */
201
  /* first (and only) entry / size, country, codepage, reserved(2), offset */
202
  filebuff[filesize++] = 12; /* size LSB */
202
  filebuff[filesize++] = 12; /* size LSB */
203
  filebuff[filesize++] = 0;  /* size MSB */
203
  filebuff[filesize++] = 0;  /* size MSB */
204
  filebuff[filesize++] = LSB(c->CTYINFO.id);   /* country LSB */
204
  filebuff[filesize++] = LSB(c->CTYINFO.id);   /* country LSB */
205
  filebuff[filesize++] = MSB(c->CTYINFO.id);   /* country MSB */
205
  filebuff[filesize++] = MSB(c->CTYINFO.id);   /* country MSB */
206
  filebuff[filesize++] = LSB(c->CTYINFO.codepage); /* codepage LSB */
206
  filebuff[filesize++] = LSB(c->CTYINFO.codepage); /* codepage LSB */
207
  filebuff[filesize++] = MSB(c->CTYINFO.codepage); /* codepage MSB */
207
  filebuff[filesize++] = MSB(c->CTYINFO.codepage); /* codepage MSB */
208
  filesize += 4;       /* reserved bytes */
208
  filesize += 4;       /* reserved bytes */
209
 
209
 
210
  filesize += 4;
210
  filesize += 4;
211
  memcpy(filebuff + filesize - 4, &filesize, sizeof(filesize));
211
  memcpy(filebuff + filesize - 4, &filesize, sizeof(filesize));
212
 
212
 
213
  /* index of subfunctions */
213
  /* index of subfunctions */
214
  filebuff[filesize] = 7; /* there are 7 subfunctions */
214
  filebuff[filesize] = 7; /* there are 7 subfunctions */
215
  filesize += 2;
215
  filesize += 2;
216
  for (x = 0; x < 7; x++) { /* dump each subfunction (size, id, offset) */
216
  for (x = 0; x < 7; x++) { /* dump each subfunction (size, id, offset) */
217
    /* size is always 6 */
217
    /* size is always 6 */
218
    filebuff[filesize] = 6;
218
    filebuff[filesize] = 6;
219
    filesize += 2;
219
    filesize += 2;
220
    /* id of the subfunction */
220
    /* id of the subfunction */
221
    filebuff[filesize++] = LSB(subfunction_id[x]);
221
    filebuff[filesize++] = LSB(subfunction_id[x]);
222
    filebuff[filesize++] = MSB(subfunction_id[x]);
222
    filebuff[filesize++] = MSB(subfunction_id[x]);
223
    /* remember the offset of the subfunction pointer for later */
223
    /* remember the offset of the subfunction pointer for later */
224
    subfunction_ptr[x] = filesize;
224
    subfunction_ptr[x] = filesize;
225
    filesize += 4;
225
    filesize += 4;
226
  }
226
  }
227
 
227
 
228
  /* write the CTYINFO subfunction */
228
  /* write the CTYINFO subfunction */
229
  memcpy(filebuff + subfunction_ptr[0], &filesize, sizeof(filesize));
229
  memcpy(filebuff + subfunction_ptr[0], &filesize, sizeof(filesize));
230
 
230
 
231
  /* subfunction header */
231
  /* subfunction header */
232
  memcpy(filebuff + filesize, "\377CTYINFO", 8);
232
  memcpy(filebuff + filesize, "\377CTYINFO", 8);
233
  filesize += 8;
233
  filesize += 8;
234
  /* subfunction size */
234
  /* subfunction size */
235
  filebuff[filesize] = 22;
235
  filebuff[filesize] = 22;
236
  filesize += 2;
236
  filesize += 2;
237
 
237
 
238
  /* country preferences */
238
  /* country preferences */
239
  memcpy(filebuff + filesize, &(c->CTYINFO), 22);
239
  memcpy(filebuff + filesize, &(c->CTYINFO), 22);
240
  filesize += 22;
240
  filesize += 22;
241
 
241
 
242
  /* write the UCASE subfunction (used for LCASE, too) */
242
  /* write the UCASE subfunction (used for LCASE, too) */
243
  memcpy(filebuff + subfunction_ptr[1], &filesize, sizeof(filesize));
243
  memcpy(filebuff + subfunction_ptr[1], &filesize, sizeof(filesize));
244
  memcpy(filebuff + subfunction_ptr[2], &filesize, sizeof(filesize));
244
  memcpy(filebuff + subfunction_ptr[2], &filesize, sizeof(filesize));
245
 
245
 
246
  /* subfunction header */
246
  /* subfunction header */
247
  memcpy(filebuff + filesize, "\377UCASE  ", 8);
247
  memcpy(filebuff + filesize, "\377UCASE  ", 8);
248
  filesize += 8;
248
  filesize += 8;
249
  /* subfunction size */
249
  /* subfunction size */
250
  filebuff[filesize++] = 128;
250
  filebuff[filesize++] = 128;
251
  filebuff[filesize++] = 0;
251
  filebuff[filesize++] = 0;
252
  /* UCASE table */
252
  /* UCASE table */
253
  memcpy(filebuff + filesize, ucase_437, 128);
253
  memcpy(filebuff + filesize, ucase_437, 128);
254
  filesize += 128;
254
  filesize += 128;
255
 
255
 
256
  /* write the FCHAR subfunction (filename terminator table) */
256
  /* write the FCHAR subfunction (filename terminator table) */
257
  memcpy(filebuff + subfunction_ptr[3], &filesize, sizeof(filesize));
257
  memcpy(filebuff + subfunction_ptr[3], &filesize, sizeof(filesize));
258
 
258
 
259
  /* subfunction header */
259
  /* subfunction header */
260
  memcpy(filebuff + filesize, "\377FCHAR  ", 8);
260
  memcpy(filebuff + filesize, "\377FCHAR  ", 8);
261
  filesize += 8;
261
  filesize += 8;
262
  /* subfunction size */
262
  /* subfunction size */
263
  filebuff[filesize++] = 22;
263
  filebuff[filesize++] = 22;
264
  filebuff[filesize++] = 0;
264
  filebuff[filesize++] = 0;
265
  /* values here are quite obscure, dumped from country.sys */
265
  /* values here are quite obscure, dumped from country.sys */
266
  filebuff[filesize++] = 142;
266
  filebuff[filesize++] = 142;
267
  filebuff[filesize++] = 0;
267
  filebuff[filesize++] = 0;
268
  filebuff[filesize++] = 255;
268
  filebuff[filesize++] = 255;
269
  filebuff[filesize++] = 65;
269
  filebuff[filesize++] = 65;
270
  filebuff[filesize++] = 0;
270
  filebuff[filesize++] = 0;
271
  filebuff[filesize++] = 32;
271
  filebuff[filesize++] = 32;
272
  filebuff[filesize++] = 238;
272
  filebuff[filesize++] = 238;
273
  /* list of characters that terminates a filename */
273
  /* list of characters that terminates a filename */
274
  filebuff[filesize++] = 14;  /* how many of them */
274
  filebuff[filesize++] = 14;  /* how many of them */
275
  filebuff[filesize++] = 46;  /* . */
275
  filebuff[filesize++] = 46;  /* . */
276
  filebuff[filesize++] = 34;  /* " */
276
  filebuff[filesize++] = 34;  /* " */
277
  filebuff[filesize++] = 47;  /* / */
277
  filebuff[filesize++] = 47;  /* / */
278
  filebuff[filesize++] = 92;  /* \ */
278
  filebuff[filesize++] = 92;  /* \ */
279
  filebuff[filesize++] = 91;  /* [ */
279
  filebuff[filesize++] = 91;  /* [ */
280
  filebuff[filesize++] = 93;  /* ] */
280
  filebuff[filesize++] = 93;  /* ] */
281
  filebuff[filesize++] = 58;  /* : */
281
  filebuff[filesize++] = 58;  /* : */
282
  filebuff[filesize++] = 124; /* | */
282
  filebuff[filesize++] = 124; /* | */
283
  filebuff[filesize++] = 60;  /* < */
283
  filebuff[filesize++] = 60;  /* < */
284
  filebuff[filesize++] = 62;  /* > */
284
  filebuff[filesize++] = 62;  /* > */
285
  filebuff[filesize++] = 43;  /* + */
285
  filebuff[filesize++] = 43;  /* + */
286
  filebuff[filesize++] = 61;  /* = */
286
  filebuff[filesize++] = 61;  /* = */
287
  filebuff[filesize++] = 59;  /* ; */
287
  filebuff[filesize++] = 59;  /* ; */
288
  filebuff[filesize++] = 44;  /* , */
288
  filebuff[filesize++] = 44;  /* , */
289
 
289
 
290
  /* write the COLLATE subfunction */
290
  /* write the COLLATE subfunction */
291
  memcpy(filebuff + subfunction_ptr[4], &filesize, sizeof(filesize));
291
  memcpy(filebuff + subfunction_ptr[4], &filesize, sizeof(filesize));
292
 
292
 
293
  /* subfunction header */
293
  /* subfunction header */
294
  memcpy(filebuff + filesize, "\377COLLATE", 8);
294
  memcpy(filebuff + filesize, "\377COLLATE", 8);
295
  filesize += 8;
295
  filesize += 8;
296
  /* subfunction size */
296
  /* subfunction size */
297
  filebuff[filesize++] = LSB(256);
297
  filebuff[filesize++] = LSB(256);
298
  filebuff[filesize++] = MSB(256);
298
  filebuff[filesize++] = MSB(256);
299
  /* collation for standard CP437 */
299
  /* collation for standard CP437 */
300
  memcpy(filebuff + filesize, collate_437, 256);
300
  memcpy(filebuff + filesize, collate_437, 256);
301
  filesize += 256;
301
  filesize += 256;
302
 
302
 
303
  /* write the DBCS subfunction */
303
  /* write the DBCS subfunction */
304
  memcpy(filebuff + subfunction_ptr[5], &filesize, sizeof(filesize));
304
  memcpy(filebuff + subfunction_ptr[5], &filesize, sizeof(filesize));
305
  /* subfunction header */
305
  /* subfunction header */
306
  memcpy(filebuff + filesize, "\377DBCS   ", 8);
306
  memcpy(filebuff + filesize, "\377DBCS   ", 8);
307
  filesize += 8;
307
  filesize += 8;
308
  /* subfunction size */
308
  /* subfunction size */
309
  filebuff[filesize++] = 0;
309
  filebuff[filesize++] = 0;
310
  filebuff[filesize++] = 0;
310
  filebuff[filesize++] = 0;
311
  /* table terminator (must be there even if no lenght is zero */
311
  /* table terminator (must be there even if no lenght is zero */
312
  filebuff[filesize++] = 0;
312
  filebuff[filesize++] = 0;
313
  filebuff[filesize++] = 0;
313
  filebuff[filesize++] = 0;
314
 
314
 
315
  /* write the YESNO subfunction */
315
  /* write the YESNO subfunction */
316
  memcpy(filebuff + subfunction_ptr[6], &filesize, sizeof(filesize));
316
  memcpy(filebuff + subfunction_ptr[6], &filesize, sizeof(filesize));
317
  memcpy(filebuff + filesize, "\377YESNO  ", 8);
317
  memcpy(filebuff + filesize, "\377YESNO  ", 8);
318
  filesize += 8;
318
  filesize += 8;
319
  filebuff[filesize] = 4;  /* size (LSB) */
319
  filebuff[filesize] = 4;  /* size (LSB) */
320
  filesize += 2;
320
  filesize += 2;
321
  memcpy(filebuff + filesize, &(c->YESNO), 4);
321
  memcpy(filebuff + filesize, &(c->YESNO), 4);
322
  filesize += 4;
322
  filesize += 4;
323
 
323
 
324
  /* write the file trailer */
324
  /* write the file trailer */
325
  memcpy(filebuff + filesize, "LOCALCFG", 8);
325
  memcpy(filebuff + filesize, "LOCALCFG", 8);
326
  filesize += 8;
326
  filesize += 8;
327
 
327
 
328
  /* write the buffer to file */
328
  /* write the buffer to file */
329
  fd = fopen(fname, "wb");
329
  fd = fopen(fname, "wb");
330
  if (fd == NULL) return(-1);
330
  if (fd == NULL) return(-1);
331
  fwrite(filebuff, 1, filesize, fd);
331
  fwrite(filebuff, 1, filesize, fd);
332
  fclose(fd);
332
  fclose(fd);
333
 
333
 
334
  return(0);
334
  return(0);
335
}
335
}
336
 
336