Subversion Repositories SvarDOS

Rev

Rev 585 | Rev 608 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 585 Rev 586
1
/*
1
/*
2
 * functions that read/write from/to the localcfg country.sys-like file.
2
 * functions that read/write from/to the localcfg country.sys-like file.
3
 * Copyright (C) Mateusz Viste 2015
3
 * Copyright (C) Mateusz Viste 2015
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
#define READSHORT(x) (short)(x[0] | (x[1] << 8))
12
#define READSHORT(x) (short)(x[0] | (x[1] << 8))
13
 
13
 
14
/* fills a country struct with default values */
14
/* fills a country struct with default values */
15
static void country_default(struct country *countrydata) {
15
static void country_default(struct country *countrydata) {
16
  /* first clears the memory */
16
  /* first clears the memory */
17
  memset(countrydata, 0, sizeof(struct country));
17
  memset(countrydata, 0, sizeof(struct country));
18
  /* fill in fields - only non-zero values */
18
  /* fill in fields - only non-zero values */
19
  countrydata->id = 1;
19
  countrydata->id = 1;
20
  countrydata->codepage = 437;
20
  countrydata->codepage = 437;
21
  /* countrydata->datefmt = COUNTRY_DATE_MDY;
21
  /* countrydata->datefmt = COUNTRY_DATE_MDY;
22
  countrydata->timefmt = COUNTRY_TIME12; */
22
  countrydata->timefmt = COUNTRY_TIME12; */
23
  countrydata->currency[0] = '$';
23
  countrydata->currency[0] = '$';
24
  countrydata->decimal = '.';
24
  countrydata->decimal = '.';
25
  countrydata->thousands = ',';
25
  countrydata->thousands = ',';
26
  countrydata->datesep = '/';
26
  countrydata->datesep = '/';
27
  countrydata->timesep = ':';
27
  countrydata->timesep = ':';
28
  countrydata->currencyprec = 2;
28
  countrydata->currencyprec = 2;
29
  /* countrydata->currencydecsym = 0; */
29
  /* countrydata->currencydecsym = 0; */
30
  /* countrydata->currencyspace = 0; */
30
  /* countrydata->currencyspace = 0; */
31
  /* countrydata->currencypos = 0; */
31
  /* countrydata->currencypos = 0; */
32
  countrydata->yes = 'Y';
32
  countrydata->yes = 'Y';
33
  countrydata->no = 'N';
33
  countrydata->no = 'N';
34
}
34
}
35
 
35
 
36
 
36
 
37
/* Loads data from a country.sys file into a country struct.
37
/* Loads data from a country.sys file into a country struct.
38
 * Returns 0 on success, non-zero otherwise. */
38
 * Returns 0 on success, non-zero otherwise. */
39
int country_read(struct country *countrydata, char *fname) {
39
int country_read(struct country *countrydata, char *fname) {
40
  unsigned char filebuff[1024];
40
  unsigned char filebuff[1024];
41
  unsigned char buff[64];
41
  unsigned char buff[64];
42
  short firstentryoffs;
42
  short firstentryoffs;
43
  unsigned char *subfunctions[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
43
  unsigned char *subfunctions[16] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
44
                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
44
                                     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
45
  short filesize;
45
  short filesize;
46
  short subfunctionscount;
46
  short subfunctionscount;
47
  unsigned char *functiondata;
47
  unsigned char *functiondata;
48
  int x;
48
  int x;
49
  FILE *fd;
49
  FILE *fd;
50
 
50
 
51
  /* preload the country struct with default values */
51
  /* preload the country struct with default values */
52
  country_default(countrydata);
52
  country_default(countrydata);
53
 
53
 
54
  /* load the file into buff, if file exists */
54
  /* load the file into buff, if file exists */
55
  fd = fopen(fname, "rb");
55
  fd = fopen(fname, "rb");
56
  if (fd == NULL) return(0); /* "file doesn't exist" is not an error condition */
56
  if (fd == NULL) return(0); /* "file doesn't exist" is not an error condition */
57
  filesize = fread(filebuff, 1, sizeof(filebuff), fd);
57
  filesize = fread(filebuff, 1, sizeof(filebuff), fd);
58
  fclose(fd);
58
  fclose(fd);
59
 
59
 
60
  /* check that it's a country file - should start with 0xFF COUNTRY 0x00 */
60
  /* check that it's a country file - should start with 0xFF COUNTRY 0x00 */
61
  if (filebuff[0] != 0xFF) return(-2);
61
  if (filebuff[0] != 0xFF) return(-2);
62
  if (strcmp((char *)filebuff + 1, "COUNTRY") != 0) return(-2);
62
  if (strcmp((char *)filebuff + 1, "COUNTRY") != 0) return(-2);
63
 
63
 
64
  /* check that it's one of my country.sys files - should contain a trailer */
64
  /* check that it's one of my country.sys files - should contain a trailer */
65
  memcpy(buff, filebuff + filesize - 8, 8);
65
  memcpy(buff, filebuff + filesize - 8, 8);
66
  buff[8] = 0;
66
  buff[8] = 0;
67
  if (strcmp((char *)buff, "LOCALCFG") != 0) return(-3);
67
  if (strcmp((char *)buff, "LOCALCFG") != 0) return(-3);
68
 
68
 
69
  /* read the offset of the entries index - must be at least 23 */
69
  /* read the offset of the entries index - must be at least 23 */
70
  functiondata = filebuff + 19;
70
  functiondata = filebuff + 19;
71
  firstentryoffs = READSHORT(functiondata);
71
  firstentryoffs = READSHORT(functiondata);
72
  if ((firstentryoffs < 23) || (firstentryoffs >= filesize)) return(-4);
72
  if ((firstentryoffs < 23) || (firstentryoffs >= filesize)) return(-4);
73
  functiondata = filebuff + firstentryoffs;
73
  functiondata = filebuff + firstentryoffs;
74
 
74
 
75
  /* how many entries do we have? I expect exactly one. */
75
  /* how many entries do we have? I expect exactly one. */
76
  if (READSHORT(functiondata) != 1) return(-5);
76
  if (READSHORT(functiondata) != 1) return(-5);
77
  /* skip to the first country entry */
77
  /* skip to the first country entry */
78
  functiondata += 2;
78
  functiondata += 2;
79
 
79
 
80
  /* skip directly to the subfunctions of the first country */
80
  /* skip directly to the subfunctions of the first country */
81
  /* ddwords: size, country, codepage, reserved, reserved, offset */
81
  /* ddwords: size, country, codepage, reserved, reserved, offset */
82
  /* printf("Size = %d\n", READSHORT(functiondata)); */
82
  /* printf("Size = %d\n", READSHORT(functiondata)); */
83
  functiondata += 2; /* skip size */
83
  functiondata += 2; /* skip size */
84
  /* printf("Country = %d\n", READSHORT(functiondata[0]); */
84
  /* printf("Country = %d\n", READSHORT(functiondata[0]); */
85
  functiondata += 2; /* skip country */
85
  functiondata += 2; /* skip country */
86
  /* printf("Codepage = %d\n", READSHORT(functiondata)); */
86
  /* printf("Codepage = %d\n", READSHORT(functiondata)); */
87
  functiondata += 2; /* skip codepage */
87
  functiondata += 2; /* skip codepage */
88
  functiondata += 4; /* skip reserved fields */
88
  functiondata += 4; /* skip reserved fields */
89
  firstentryoffs = READSHORT(functiondata); /* read offset of the subfunctions index */
89
  firstentryoffs = READSHORT(functiondata); /* read offset of the subfunctions index */
90
  functiondata = filebuff + firstentryoffs;
90
  functiondata = filebuff + firstentryoffs;
91
 
91
 
92
  /* read all subfunctions, but no more than 15 */
92
  /* read all subfunctions, but no more than 15 */
93
  subfunctionscount = READSHORT(functiondata);
93
  subfunctionscount = READSHORT(functiondata);
94
  /* printf("Found %d subfunctions\n", subfunctionscount); */
94
  /* printf("Found %d subfunctions\n", subfunctionscount); */
95
  functiondata += 2;
95
  functiondata += 2;
96
  for (x = 0; (x < 15) && (x < subfunctionscount); x++) {
96
  for (x = 0; (x < 15) && (x < subfunctionscount); x++) {
97
    short size = READSHORT(functiondata);
97
    short size = READSHORT(functiondata);
98
    functiondata += 2;
98
    functiondata += 2;
99
    functiondata += 2; /* skip ID of the subfunction */
99
    functiondata += 2; /* skip ID of the subfunction */
100
    subfunctions[x] = filebuff + READSHORT(functiondata);
100
    subfunctions[x] = filebuff + READSHORT(functiondata);
101
    /* printf("subfunction %d at 0x%p\n", x, subfunctions[x]); */
101
    /* printf("subfunction %d at 0x%p\n", x, subfunctions[x]); */
102
    functiondata += size - 2;
102
    functiondata += size - 2;
103
  }
103
  }
104
 
104
 
105
  /* load every subfunction, and feed the country struct with data */
105
  /* load every subfunction, and feed the country struct with data */
106
  for (x = 0; subfunctions[x] != NULL; x++) {
106
  for (x = 0; subfunctions[x] != NULL; x++) {
107
    short functionsize;
107
    short functionsize;
108
    /* the function name should always start with 0xFF */
108
    /* the function name should always start with 0xFF */
109
    if (subfunctions[x][0] != 0xFF) return(-6);
109
    if (subfunctions[x][0] != 0xFF) return(-6);
110
    /* load the subfunction's name, and act accordingly */
110
    /* load the subfunction's name, and act accordingly */
111
    memcpy(buff, subfunctions[x] + 1, 7);
111
    memcpy(buff, subfunctions[x] + 1, 7);
112
    buff[7] = 0;
112
    buff[7] = 0;
113
    functiondata = subfunctions[x] + 8;
113
    functiondata = subfunctions[x] + 8;
114
    functionsize = READSHORT(functiondata);
114
    functionsize = READSHORT(functiondata);
115
    functiondata = subfunctions[x] + 10;
115
    functiondata = subfunctions[x] + 10;
116
    /* */
116
    /* */
117
    if (strcmp((char *)buff, "YESNO  ") == 0) {
117
    if (strcmp((char *)buff, "YESNO  ") == 0) {
118
      if (functionsize != 4) continue;
118
      if (functionsize != 4) continue;
119
      countrydata->yes = functiondata[0];
119
      countrydata->yes = functiondata[0];
120
      countrydata->no = functiondata[2];
120
      countrydata->no = functiondata[2];
121
    } else if (strcmp((char *)buff, "CTYINFO") == 0) {
121
    } else if (strcmp((char *)buff, "CTYINFO") == 0) {
122
      if (functionsize != 22) continue;
122
      if (functionsize != 22) continue;
123
      /* ID */
123
      /* ID */
124
      countrydata->id = READSHORT(functiondata);
124
      countrydata->id = READSHORT(functiondata);
125
      functiondata += 2;
125
      functiondata += 2;
126
      /* codepage */
126
      /* codepage */
127
      countrydata->codepage = READSHORT(functiondata);
127
      countrydata->codepage = READSHORT(functiondata);
128
      functiondata += 2;
128
      functiondata += 2;
129
      /* date format */
129
      /* date format */
130
      countrydata->datefmt = READSHORT(functiondata);
130
      countrydata->datefmt = READSHORT(functiondata);
131
      functiondata += 2;
131
      functiondata += 2;
132
      /* currency symbol */
132
      /* currency symbol */
133
      countrydata->currency[0] = functiondata[0];
133
      countrydata->currency[0] = functiondata[0];
134
      countrydata->currency[1] = functiondata[1];
134
      countrydata->currency[1] = functiondata[1];
135
      countrydata->currency[2] = functiondata[2];
135
      countrydata->currency[2] = functiondata[2];
136
      countrydata->currency[3] = functiondata[3];
136
      countrydata->currency[3] = functiondata[3];
137
      countrydata->currency[4] = 0;
137
      countrydata->currency[4] = 0;
138
      functiondata += 5;
138
      functiondata += 5;
139
      /* thousands separator, decimal sep, date sep, time sep */
139
      /* thousands separator, decimal sep, date sep, time sep */
140
      countrydata->thousands = READSHORT(functiondata);
140
      countrydata->thousands = READSHORT(functiondata);
141
      functiondata += 2;
141
      functiondata += 2;
142
      countrydata->decimal = READSHORT(functiondata);
142
      countrydata->decimal = READSHORT(functiondata);
143
      functiondata += 2;
143
      functiondata += 2;
144
      countrydata->datesep = READSHORT(functiondata);
144
      countrydata->datesep = READSHORT(functiondata);
145
      functiondata += 2;
145
      functiondata += 2;
146
      countrydata->timesep = READSHORT(functiondata);
146
      countrydata->timesep = READSHORT(functiondata);
147
      functiondata += 2;
147
      functiondata += 2;
148
      /* currency format */
148
      /* currency format */
149
      countrydata->currencypos = *functiondata & 1;
149
      countrydata->currencypos = *functiondata & 1;
150
      countrydata->currencyspace = (*functiondata >> 1) & 1;
150
      countrydata->currencyspace = (*functiondata >> 1) & 1;
151
      countrydata->currencydecsym = (*functiondata >> 2) & 1;
151
      countrydata->currencydecsym = (*functiondata >> 2) & 1;
152
      functiondata += 1;
152
      functiondata += 1;
153
      /* currency precision */
153
      /* currency precision */
154
      countrydata->currencyprec = *functiondata;
154
      countrydata->currencyprec = *functiondata;
155
      functiondata += 1;
155
      functiondata += 1;
156
      /* time format */
156
      /* time format */
157
      countrydata->timefmt = *functiondata;
157
      countrydata->timefmt = *functiondata;
158
      functiondata += 1;
158
      functiondata += 1;
159
    }
159
    }
160
  }
160
  }
161
 
161
 
162
  return(0);
162
  return(0);
163
}
163
}
164
 
164
 
165
 
165
 
166
#define MSB(x) (((x) >> 8) & 0xff)
166
#define MSB(x) (((x) >> 8) & 0xff)
167
#define LSB(x) ((x) & 0xff)
167
#define LSB(x) ((x) & 0xff)
168
 
168
 
169
#define DWORDB1(x) ((x) & 0xff)
169
#define DWORDB1(x) ((x) & 0xff)
170
#define DWORDB2(x) (((x) >> 8) & 0xff)
170
#define DWORDB2(x) (((x) >> 8) & 0xff)
171
#define DWORDB3(x) (((x) >> 16) & 0xff)
171
#define DWORDB3(x) (((x) >> 16) & 0xff)
172
#define DWORDB4(x) (((x) >> 24) & 0xff)
172
#define DWORDB4(x) (((x) >> 24) & 0xff)
173
 
173
 
174
 
174
 
175
/* Computes a new country.sys file based on data from a country struct.
175
/* Computes a new country.sys file based on data from a country struct.
176
 * Returns 0 on success, non-zero otherwise. */
176
 * Returns 0 on success, non-zero otherwise. */
177
int country_write(char *fname, struct country *c) {
177
int country_write(char *fname, struct country *c) {
178
  unsigned char filebuff[1024];
178
  unsigned char filebuff[1024];
179
  short filesize = 0;
179
  short filesize = 0;
180
  FILE *fd;
180
  FILE *fd;
181
  int x;
181
  int x;
182
  short subfunction_id[7] = {1,2,4,5,6,7,35};
182
  short subfunction_id[7] = {1,2,4,5,6,7,35};
183
  short subfunction_ptr[7];
183
  short subfunction_ptr[7];
184
 
184
 
185
  const unsigned char ucase_437[128] = {128, 154,  69,  65, 142,  65, 143, 128,
185
  const unsigned char ucase_437[128] = {128, 154,  69,  65, 142,  65, 143, 128,
186
                                         69,  69,  69,  73,  73,  73, 142, 143,
186
                                         69,  69,  69,  73,  73,  73, 142, 143,
187
                                        144, 146, 146,  79, 153,  79,  85,  85,
187
                                        144, 146, 146,  79, 153,  79,  85,  85,
188
                                         89, 153, 154, 155, 156, 157, 158, 159,
188
                                         89, 153, 154, 155, 156, 157, 158, 159,
189
                                         65,  73,  79,  85, 165, 165, 166, 167,
189
                                         65,  73,  79,  85, 165, 165, 166, 167,
190
                                        168, 169, 170, 171, 172, 173, 174, 175,
190
                                        168, 169, 170, 171, 172, 173, 174, 175,
191
                                        176, 177, 178, 179, 180, 181, 182, 183,
191
                                        176, 177, 178, 179, 180, 181, 182, 183,
192
                                        184, 185, 186, 187, 188, 189, 190, 191,
192
                                        184, 185, 186, 187, 188, 189, 190, 191,
193
                                        192, 193, 194, 195, 196, 197, 198, 199,
193
                                        192, 193, 194, 195, 196, 197, 198, 199,
194
                                        200, 201, 202, 203, 204, 205, 206, 207,
194
                                        200, 201, 202, 203, 204, 205, 206, 207,
195
                                        208, 209, 210, 211, 212, 213, 214, 215,
195
                                        208, 209, 210, 211, 212, 213, 214, 215,
196
                                        216, 217, 218, 219, 220, 221, 222, 223,
196
                                        216, 217, 218, 219, 220, 221, 222, 223,
197
                                        224, 225, 226, 227, 228, 229, 230, 231,
197
                                        224, 225, 226, 227, 228, 229, 230, 231,
198
                                        232, 233, 234, 235, 236, 237, 238, 239,
198
                                        232, 233, 234, 235, 236, 237, 238, 239,
199
                                        240, 241, 242, 243, 244, 245, 246, 247,
199
                                        240, 241, 242, 243, 244, 245, 246, 247,
200
                                        248, 249, 250, 251, 252, 253, 254, 255};
200
                                        248, 249, 250, 251, 252, 253, 254, 255};
201
 
201
 
202
  const unsigned char collate_437[256] = {  0,   1,   2,   3,   4,   5,   6,   7,
202
  const unsigned char collate_437[256] = {  0,   1,   2,   3,   4,   5,   6,   7,
203
                                            8,   9,  10,  11,  12,  13,  14,  15,
203
                                            8,   9,  10,  11,  12,  13,  14,  15,
204
                                           16,  17,  18,  19,  20,  21,  22,  23,
204
                                           16,  17,  18,  19,  20,  21,  22,  23,
205
                                           24,  25,  26,  27,  28,  29,  30,  31,
205
                                           24,  25,  26,  27,  28,  29,  30,  31,
206
                                           32,  33,  34,  35,  36,  37,  38,  39,
206
                                           32,  33,  34,  35,  36,  37,  38,  39,
207
                                           40,  41,  42,  43,  44,  45,  46,  47,
207
                                           40,  41,  42,  43,  44,  45,  46,  47,
208
                                           48,  49,  50,  51,  52,  53,  54,  55,
208
                                           48,  49,  50,  51,  52,  53,  54,  55,
209
                                           56,  57,  58,  59,  60,  61,  62,  63,
209
                                           56,  57,  58,  59,  60,  61,  62,  63,
210
                                           64,  65,  66,  67,  68,  69,  70,  71,
210
                                           64,  65,  66,  67,  68,  69,  70,  71,
211
                                           72,  73,  74,  75,  76,  77,  78,  79,
211
                                           72,  73,  74,  75,  76,  77,  78,  79,
212
                                           80,  81,  82,  83,  84,  85,  86,  87,
212
                                           80,  81,  82,  83,  84,  85,  86,  87,
213
                                           88,  89,  90,  91,  92,  93,  94,  95,
213
                                           88,  89,  90,  91,  92,  93,  94,  95,
214
                                           96,  65,  66,  67,  68,  69,  70,  71,
214
                                           96,  65,  66,  67,  68,  69,  70,  71,
215
                                           72,  73,  74,  75,  76,  77,  78,  79,
215
                                           72,  73,  74,  75,  76,  77,  78,  79,
216
                                           80,  81,  82,  83,  84,  85,  86,  87,
216
                                           80,  81,  82,  83,  84,  85,  86,  87,
217
                                           88,  89,  90, 123, 124, 125, 126, 127,
217
                                           88,  89,  90, 123, 124, 125, 126, 127,
218
                                           67,  85,  69,  65,  65,  65,  65,  67,
218
                                           67,  85,  69,  65,  65,  65,  65,  67,
219
                                           69,  69,  69,  73,  73,  73,  65,  65,
219
                                           69,  69,  69,  73,  73,  73,  65,  65,
220
                                           69,  65,  65,  79,  79,  79,  85,  85,
220
                                           69,  65,  65,  79,  79,  79,  85,  85,
221
                                           89,  79,  85,  36,  36,  36,  36,  36,
221
                                           89,  79,  85,  36,  36,  36,  36,  36,
222
                                           65,  73,  79,  85,  78,  78, 166, 167,
222
                                           65,  73,  79,  85,  78,  78, 166, 167,
223
                                           63, 169, 170, 171, 172,  33,  34,  34,
223
                                           63, 169, 170, 171, 172,  33,  34,  34,
224
                                          176, 177, 178, 179, 180, 181, 182, 183,
224
                                          176, 177, 178, 179, 180, 181, 182, 183,
225
                                          184, 185, 186, 187, 188, 189, 190, 191,
225
                                          184, 185, 186, 187, 188, 189, 190, 191,
226
                                          192, 193, 194, 195, 196, 197, 198, 199,
226
                                          192, 193, 194, 195, 196, 197, 198, 199,
227
                                          200, 201, 202, 203, 204, 205, 206, 207,
227
                                          200, 201, 202, 203, 204, 205, 206, 207,
228
                                          208, 209, 210, 211, 212, 213, 214, 215,
228
                                          208, 209, 210, 211, 212, 213, 214, 215,
229
                                          216, 217, 218, 219, 220, 221, 222, 223,
229
                                          216, 217, 218, 219, 220, 221, 222, 223,
230
                                          224,  83, 226, 227, 228, 229, 230, 231,
230
                                          224,  83, 226, 227, 228, 229, 230, 231,
231
                                          232, 233, 234, 235, 236, 237, 238, 239,
231
                                          232, 233, 234, 235, 236, 237, 238, 239,
232
                                          240, 241, 242, 243, 244, 245, 246, 247,
232
                                          240, 241, 242, 243, 244, 245, 246, 247,
233
                                          248, 249, 250, 251, 252, 253, 254, 255};
233
                                          248, 249, 250, 251, 252, 253, 254, 255};
234
 
234
 
235
  /* compute the country.sys structures */
235
  /* compute the country.sys structures */
236
  memcpy(filebuff, "\377COUNTRY\0\0\0\0\0\0\0\0\1\0\1", 19); /* header */
236
  memcpy(filebuff, "\377COUNTRY\0\0\0\0\0\0\0\0\1\0\1", 19); /* header */
237
  filesize = 19;
237
  filesize = 19;
238
  /* first entry offset (always current offset+4) */
238
  /* first entry offset (always current offset+4) */
239
  filebuff[filesize + 0] = DWORDB1(filesize+4);
239
  filebuff[filesize + 0] = DWORDB1(filesize+4);
240
  filebuff[filesize + 1] = DWORDB2(filesize+4);
240
  filebuff[filesize + 1] = DWORDB2(filesize+4);
241
  filebuff[filesize + 2] = DWORDB3(filesize+4);
241
  filebuff[filesize + 2] = DWORDB3(filesize+4);
242
  filebuff[filesize + 3] = DWORDB4(filesize+4);
242
  filebuff[filesize + 3] = DWORDB4(filesize+4);
243
  filesize += 4;
243
  filesize += 4;
244
  /* number of entries */
244
  /* number of entries */
245
  filebuff[filesize++] = 1;
245
  filebuff[filesize++] = 1;
246
  filebuff[filesize++] = 0;
246
  filebuff[filesize++] = 0;
247
  /* first (and only) entry / size, country, codepage, reserved(2), offset */
247
  /* first (and only) entry / size, country, codepage, reserved(2), offset */
248
  filebuff[filesize++] = 12; /* size LSB */
248
  filebuff[filesize++] = 12; /* size LSB */
249
  filebuff[filesize++] = 0;  /* size MSB */
249
  filebuff[filesize++] = 0;  /* size MSB */
250
  filebuff[filesize++] = LSB(c->id);   /* country LSB */
250
  filebuff[filesize++] = LSB(c->id);   /* country LSB */
251
  filebuff[filesize++] = MSB(c->id);   /* country MSB */
251
  filebuff[filesize++] = MSB(c->id);   /* country MSB */
252
  filebuff[filesize++] = LSB(c->codepage); /* codepage LSB */
252
  filebuff[filesize++] = LSB(c->codepage); /* codepage LSB */
253
  filebuff[filesize++] = MSB(c->codepage); /* codepage MSB */
253
  filebuff[filesize++] = MSB(c->codepage); /* codepage MSB */
254
  filebuff[filesize++] = 0; /* reserved */
254
  filebuff[filesize++] = 0; /* reserved */
255
  filebuff[filesize++] = 0; /* reserved */
255
  filebuff[filesize++] = 0; /* reserved */
256
  filebuff[filesize++] = 0; /* reserved */
256
  filebuff[filesize++] = 0; /* reserved */
257
  filebuff[filesize++] = 0; /* reserved */
257
  filebuff[filesize++] = 0; /* reserved */
258
  filebuff[filesize + 0] = DWORDB1(filesize+4); /* offset for subfunctions list (ptr + 4) */
258
  filebuff[filesize + 0] = DWORDB1(filesize+4); /* offset for subfunctions list (ptr + 4) */
259
  filebuff[filesize + 1] = DWORDB2(filesize+4); /* offset for subfunctions list (ptr + 4) */
259
  filebuff[filesize + 1] = DWORDB2(filesize+4); /* offset for subfunctions list (ptr + 4) */
260
  filebuff[filesize + 2] = DWORDB3(filesize+4); /* offset for subfunctions list (ptr + 4) */
260
  filebuff[filesize + 2] = DWORDB3(filesize+4); /* offset for subfunctions list (ptr + 4) */
261
  filebuff[filesize + 3] = DWORDB4(filesize+4); /* offset for subfunctions list (ptr + 4) */
261
  filebuff[filesize + 3] = DWORDB4(filesize+4); /* offset for subfunctions list (ptr + 4) */
262
  filesize += 4;
262
  filesize += 4;
263
  /* index of subfunctions */
263
  /* index of subfunctions */
264
  filebuff[filesize++] = 7; /* there are 7 subfunctions */
264
  filebuff[filesize++] = 7; /* there are 7 subfunctions */
265
  filebuff[filesize++] = 0;
265
  filebuff[filesize++] = 0;
266
  for (x = 0; x < 7; x++) { /* dump each subfunction (size, id, offset) */
266
  for (x = 0; x < 7; x++) { /* dump each subfunction (size, id, offset) */
267
    /* size is always 6 */
267
    /* size is always 6 */
268
    filebuff[filesize++] = 6;
268
    filebuff[filesize++] = 6;
269
    filebuff[filesize++] = 0;
269
    filebuff[filesize++] = 0;
270
    /* id of the subfunction */
270
    /* id of the subfunction */
271
    filebuff[filesize++] = LSB(subfunction_id[x]);
271
    filebuff[filesize++] = LSB(subfunction_id[x]);
272
    filebuff[filesize++] = MSB(subfunction_id[x]);
272
    filebuff[filesize++] = MSB(subfunction_id[x]);
273
    /* remember the offset of the subfunction pointer for later */
273
    /* remember the offset of the subfunction pointer for later */
274
    subfunction_ptr[x] = filesize;
274
    subfunction_ptr[x] = filesize;
275
    filesize += 4;
275
    filesize += 4;
276
  }
276
  }
277
  /* write the CTYINFO subfunction */
277
  /* write the CTYINFO subfunction */
278
  filebuff[subfunction_ptr[0]+0] = DWORDB1(filesize); /* update the    */
278
  filebuff[subfunction_ptr[0]+0] = DWORDB1(filesize); /* update the    */
279
  filebuff[subfunction_ptr[0]+1] = DWORDB2(filesize); /* subfunction   */
279
  filebuff[subfunction_ptr[0]+1] = DWORDB2(filesize); /* subfunction   */
280
  filebuff[subfunction_ptr[0]+2] = DWORDB3(filesize); /* pointer with  */
280
  filebuff[subfunction_ptr[0]+2] = DWORDB3(filesize); /* pointer with  */
281
  filebuff[subfunction_ptr[0]+3] = DWORDB4(filesize); /* correct value */
281
  filebuff[subfunction_ptr[0]+3] = DWORDB4(filesize); /* correct value */
282
  /* subfunction header */
282
  /* subfunction header */
283
  memcpy(filebuff + filesize, "\377CTYINFO", 8);
283
  memcpy(filebuff + filesize, "\377CTYINFO", 8);
284
  filesize += 8;
284
  filesize += 8;
285
  /* subfunction size */
285
  /* subfunction size */
286
  filebuff[filesize++] = 22;
286
  filebuff[filesize++] = 22;
287
  filebuff[filesize++] = 0;
287
  filebuff[filesize++] = 0;
288
  /* country preferences */
288
  /* country preferences */
289
  filebuff[filesize++] = LSB(c->id); /* ID */
289
  filebuff[filesize++] = LSB(c->id); /* ID */
290
  filebuff[filesize++] = MSB(c->id); /* ID */
290
  filebuff[filesize++] = MSB(c->id); /* ID */
291
  filebuff[filesize++] = LSB(c->codepage); /* CP */
291
  filebuff[filesize++] = LSB(c->codepage); /* CP */
292
  filebuff[filesize++] = MSB(c->codepage); /* CP */
292
  filebuff[filesize++] = MSB(c->codepage); /* CP */
293
  filebuff[filesize++] = LSB(c->datefmt); /* date format */
293
  filebuff[filesize++] = LSB(c->datefmt); /* date format */
294
  filebuff[filesize++] = MSB(c->datefmt); /* date format */
294
  filebuff[filesize++] = MSB(c->datefmt); /* date format */
295
  for (x = 0; x < 5; x++) {
295
  for (x = 0; x < 5; x++) {
296
    filebuff[filesize++] = c->currency[x]; /* currency */
296
    filebuff[filesize++] = c->currency[x]; /* currency */
297
  }
297
  }
298
  filebuff[filesize++] = LSB(c->thousands);  /* thousands separator LSB */
298
  filebuff[filesize++] = LSB(c->thousands);  /* thousands separator LSB */
299
  filebuff[filesize++] = MSB(c->thousands);  /* thousands separator MSB */
299
  filebuff[filesize++] = MSB(c->thousands);  /* thousands separator MSB */
300
  filebuff[filesize++] = LSB(c->decimal);    /* decimal separator LSB */
300
  filebuff[filesize++] = LSB(c->decimal);    /* decimal separator LSB */
301
  filebuff[filesize++] = MSB(c->decimal);    /* decimal separator MSB */
301
  filebuff[filesize++] = MSB(c->decimal);    /* decimal separator MSB */
302
  filebuff[filesize++] = LSB(c->datesep);    /* date separator LSB */
302
  filebuff[filesize++] = LSB(c->datesep);    /* date separator LSB */
303
  filebuff[filesize++] = MSB(c->datesep);    /* date separator MSB */
303
  filebuff[filesize++] = MSB(c->datesep);    /* date separator MSB */
304
  filebuff[filesize++] = LSB(c->timesep);    /* time separator LSB */
304
  filebuff[filesize++] = LSB(c->timesep);    /* time separator LSB */
305
  filebuff[filesize++] = MSB(c->timesep);    /* time separator MSB */
305
  filebuff[filesize++] = MSB(c->timesep);    /* time separator MSB */
306
  filebuff[filesize] = c->currencydecsym; /* currency format (bit 2) */
306
  filebuff[filesize] = c->currencydecsym; /* currency format (bit 2) */
307
  filebuff[filesize] <<= 8;
307
  filebuff[filesize] <<= 8;
308
  filebuff[filesize] |= c->currencyspace; /* currency format (bit 1) */
308
  filebuff[filesize] |= c->currencyspace; /* currency format (bit 1) */
309
  filebuff[filesize] <<= 8;
309
  filebuff[filesize] <<= 8;
310
  filebuff[filesize++] |= c->currencypos; /* currency format (bit 0) */
310
  filebuff[filesize++] |= c->currencypos; /* currency format (bit 0) */
311
  filebuff[filesize++] = c->currencyprec; /* currency precision */
311
  filebuff[filesize++] = c->currencyprec; /* currency precision */
312
  filebuff[filesize++] = c->timefmt;      /* time format */
312
  filebuff[filesize++] = c->timefmt;      /* time format */
313
 
313
 
314
  /* write the UCASE subfunction (used for LCASE, too) */
314
  /* write the UCASE subfunction (used for LCASE, too) */
315
  filebuff[subfunction_ptr[1]+0] = DWORDB1(filesize); /* update the    */
315
  filebuff[subfunction_ptr[1]+0] = DWORDB1(filesize); /* update the    */
316
  filebuff[subfunction_ptr[1]+1] = DWORDB2(filesize); /* subfunction   */
316
  filebuff[subfunction_ptr[1]+1] = DWORDB2(filesize); /* subfunction   */
317
  filebuff[subfunction_ptr[1]+2] = DWORDB3(filesize); /* pointer with  */
317
  filebuff[subfunction_ptr[1]+2] = DWORDB3(filesize); /* pointer with  */
318
  filebuff[subfunction_ptr[1]+3] = DWORDB4(filesize); /* correct value */
318
  filebuff[subfunction_ptr[1]+3] = DWORDB4(filesize); /* correct value */
319
  filebuff[subfunction_ptr[2]+0] = DWORDB1(filesize); /* update the    */
319
  filebuff[subfunction_ptr[2]+0] = DWORDB1(filesize); /* update the    */
320
  filebuff[subfunction_ptr[2]+1] = DWORDB2(filesize); /* subfunction   */
320
  filebuff[subfunction_ptr[2]+1] = DWORDB2(filesize); /* subfunction   */
321
  filebuff[subfunction_ptr[2]+2] = DWORDB3(filesize); /* pointer with  */
321
  filebuff[subfunction_ptr[2]+2] = DWORDB3(filesize); /* pointer with  */
322
  filebuff[subfunction_ptr[2]+3] = DWORDB4(filesize); /* correct value */
322
  filebuff[subfunction_ptr[2]+3] = DWORDB4(filesize); /* correct value */
323
  /* subfunction header */
323
  /* subfunction header */
324
  memcpy(filebuff + filesize, "\377UCASE  ", 8);
324
  memcpy(filebuff + filesize, "\377UCASE  ", 8);
325
  filesize += 8;
325
  filesize += 8;
326
  /* subfunction size */
326
  /* subfunction size */
327
  filebuff[filesize++] = 128;
327
  filebuff[filesize++] = 128;
328
  filebuff[filesize++] = 0;
328
  filebuff[filesize++] = 0;
329
  /* UCASE table */
329
  /* UCASE table */
330
  for (x = 0; x < 128; x++) {
330
  for (x = 0; x < 128; x++) {
331
    filebuff[filesize++] = ucase_437[x];
331
    filebuff[filesize++] = ucase_437[x];
332
  }
332
  }
333
 
333
 
334
  /* write the FCHAR subfunction (filename terminator table) */
334
  /* write the FCHAR subfunction (filename terminator table) */
335
  filebuff[subfunction_ptr[3]+0] = DWORDB1(filesize); /* update the    */
335
  filebuff[subfunction_ptr[3]+0] = DWORDB1(filesize); /* update the    */
336
  filebuff[subfunction_ptr[3]+1] = DWORDB2(filesize); /* subfunction   */
336
  filebuff[subfunction_ptr[3]+1] = DWORDB2(filesize); /* subfunction   */
337
  filebuff[subfunction_ptr[3]+2] = DWORDB3(filesize); /* pointer with  */
337
  filebuff[subfunction_ptr[3]+2] = DWORDB3(filesize); /* pointer with  */
338
  filebuff[subfunction_ptr[3]+3] = DWORDB4(filesize); /* correct value */
338
  filebuff[subfunction_ptr[3]+3] = DWORDB4(filesize); /* correct value */
339
  /* subfunction header */
339
  /* subfunction header */
340
  memcpy(filebuff + filesize, "\377FCHAR  ", 8);
340
  memcpy(filebuff + filesize, "\377FCHAR  ", 8);
341
  filesize += 8;
341
  filesize += 8;
342
  /* subfunction size */
342
  /* subfunction size */
343
  filebuff[filesize++] = 22;
343
  filebuff[filesize++] = 22;
344
  filebuff[filesize++] = 0;
344
  filebuff[filesize++] = 0;
345
  /* values here are quite obscure, dumped from country.sys */
345
  /* values here are quite obscure, dumped from country.sys */
346
  filebuff[filesize++] = 142;
346
  filebuff[filesize++] = 142;
347
  filebuff[filesize++] = 0;
347
  filebuff[filesize++] = 0;
348
  filebuff[filesize++] = 255;
348
  filebuff[filesize++] = 255;
349
  filebuff[filesize++] = 65;
349
  filebuff[filesize++] = 65;
350
  filebuff[filesize++] = 0;
350
  filebuff[filesize++] = 0;
351
  filebuff[filesize++] = 32;
351
  filebuff[filesize++] = 32;
352
  filebuff[filesize++] = 238;
352
  filebuff[filesize++] = 238;
353
  /* list of characters that terminates a filename */
353
  /* list of characters that terminates a filename */
354
  filebuff[filesize++] = 14;  /* how many of them */
354
  filebuff[filesize++] = 14;  /* how many of them */
355
  filebuff[filesize++] = 46;  /* . */
355
  filebuff[filesize++] = 46;  /* . */
356
  filebuff[filesize++] = 34;  /* " */
356
  filebuff[filesize++] = 34;  /* " */
357
  filebuff[filesize++] = 47;  /* / */
357
  filebuff[filesize++] = 47;  /* / */
358
  filebuff[filesize++] = 92;  /* \ */
358
  filebuff[filesize++] = 92;  /* \ */
359
  filebuff[filesize++] = 91;  /* [ */
359
  filebuff[filesize++] = 91;  /* [ */
360
  filebuff[filesize++] = 93;  /* ] */
360
  filebuff[filesize++] = 93;  /* ] */
361
  filebuff[filesize++] = 58;  /* : */
361
  filebuff[filesize++] = 58;  /* : */
362
  filebuff[filesize++] = 124; /* | */
362
  filebuff[filesize++] = 124; /* | */
363
  filebuff[filesize++] = 60;  /* < */
363
  filebuff[filesize++] = 60;  /* < */
364
  filebuff[filesize++] = 62;  /* > */
364
  filebuff[filesize++] = 62;  /* > */
365
  filebuff[filesize++] = 43;  /* + */
365
  filebuff[filesize++] = 43;  /* + */
366
  filebuff[filesize++] = 61;  /* = */
366
  filebuff[filesize++] = 61;  /* = */
367
  filebuff[filesize++] = 59;  /* ; */
367
  filebuff[filesize++] = 59;  /* ; */
368
  filebuff[filesize++] = 44;  /* , */
368
  filebuff[filesize++] = 44;  /* , */
369
 
369
 
370
  /* write the COLLATE subfunction */
370
  /* write the COLLATE subfunction */
371
  filebuff[subfunction_ptr[4]+0] = DWORDB1(filesize); /* update the    */
371
  filebuff[subfunction_ptr[4]+0] = DWORDB1(filesize); /* update the    */
372
  filebuff[subfunction_ptr[4]+1] = DWORDB2(filesize); /* subfunction   */
372
  filebuff[subfunction_ptr[4]+1] = DWORDB2(filesize); /* subfunction   */
373
  filebuff[subfunction_ptr[4]+2] = DWORDB3(filesize); /* pointer with  */
373
  filebuff[subfunction_ptr[4]+2] = DWORDB3(filesize); /* pointer with  */
374
  filebuff[subfunction_ptr[4]+3] = DWORDB4(filesize); /* correct value */
374
  filebuff[subfunction_ptr[4]+3] = DWORDB4(filesize); /* correct value */
375
  /* subfunction header */
375
  /* subfunction header */
376
  memcpy(filebuff + filesize, "\377COLLATE", 8);
376
  memcpy(filebuff + filesize, "\377COLLATE", 8);
377
  filesize += 8;
377
  filesize += 8;
378
  /* subfunction size */
378
  /* subfunction size */
379
  filebuff[filesize++] = LSB(256);
379
  filebuff[filesize++] = LSB(256);
380
  filebuff[filesize++] = MSB(256);
380
  filebuff[filesize++] = MSB(256);
381
  /* collation for standard CP437 */
381
  /* collation for standard CP437 */
382
  for (x = 0; x < 256; x++) {
382
  for (x = 0; x < 256; x++) {
383
    filebuff[filesize++] = collate_437[x];
383
    filebuff[filesize++] = collate_437[x];
384
  }
384
  }
385
 
385
 
386
  /* write the DBCS subfunction */
386
  /* write the DBCS subfunction */
387
  filebuff[subfunction_ptr[5]+0] = DWORDB1(filesize); /* update the    */
387
  filebuff[subfunction_ptr[5]+0] = DWORDB1(filesize); /* update the    */
388
  filebuff[subfunction_ptr[5]+1] = DWORDB2(filesize); /* subfunction   */
388
  filebuff[subfunction_ptr[5]+1] = DWORDB2(filesize); /* subfunction   */
389
  filebuff[subfunction_ptr[5]+2] = DWORDB3(filesize); /* pointer with  */
389
  filebuff[subfunction_ptr[5]+2] = DWORDB3(filesize); /* pointer with  */
390
  filebuff[subfunction_ptr[5]+3] = DWORDB4(filesize); /* correct value */
390
  filebuff[subfunction_ptr[5]+3] = DWORDB4(filesize); /* correct value */
391
  /* subfunction header */
391
  /* subfunction header */
392
  memcpy(filebuff + filesize, "\377DBCS   ", 8);
392
  memcpy(filebuff + filesize, "\377DBCS   ", 8);
393
  filesize += 8;
393
  filesize += 8;
394
  /* subfunction size */
394
  /* subfunction size */
395
  filebuff[filesize++] = 0;
395
  filebuff[filesize++] = 0;
396
  filebuff[filesize++] = 0;
396
  filebuff[filesize++] = 0;
397
  /* table terminator (must be there even if no lenght is zero */
397
  /* table terminator (must be there even if no lenght is zero */
398
  filebuff[filesize++] = 0;
398
  filebuff[filesize++] = 0;
399
  filebuff[filesize++] = 0;
399
  filebuff[filesize++] = 0;
400
 
400
 
401
  /* write the YESNO subfunction */
401
  /* write the YESNO subfunction */
402
  filebuff[subfunction_ptr[6]+0] = DWORDB1(filesize); /* update the    */
402
  filebuff[subfunction_ptr[6]+0] = DWORDB1(filesize); /* update the    */
403
  filebuff[subfunction_ptr[6]+1] = DWORDB2(filesize); /* subfunction   */
403
  filebuff[subfunction_ptr[6]+1] = DWORDB2(filesize); /* subfunction   */
404
  filebuff[subfunction_ptr[6]+2] = DWORDB3(filesize); /* pointer with  */
404
  filebuff[subfunction_ptr[6]+2] = DWORDB3(filesize); /* pointer with  */
405
  filebuff[subfunction_ptr[6]+3] = DWORDB4(filesize); /* correct value */
405
  filebuff[subfunction_ptr[6]+3] = DWORDB4(filesize); /* correct value */
406
  memcpy(filebuff + filesize, "\377YESNO  ", 8);
406
  memcpy(filebuff + filesize, "\377YESNO  ", 8);
407
  filesize += 8;
407
  filesize += 8;
408
  filebuff[filesize++] = 4;  /* size (LSB) */
408
  filebuff[filesize++] = 4;  /* size (LSB) */
409
  filebuff[filesize++] = 0;  /* size (MSB) */
409
  filebuff[filesize++] = 0;  /* size (MSB) */
410
  filebuff[filesize++] = c->yes;  /* "Yes" letter */
410
  filebuff[filesize++] = c->yes;  /* "Yes" letter */
411
  filebuff[filesize++] = 0;
411
  filebuff[filesize++] = 0;
412
  filebuff[filesize++] = c->no;   /* "No" letter */
412
  filebuff[filesize++] = c->no;   /* "No" letter */
413
  filebuff[filesize++] = 0;
413
  filebuff[filesize++] = 0;
414
 
414
 
415
  /* write the file trailer */
415
  /* write the file trailer */
416
  memcpy(filebuff + filesize, "LOCALCFG", 8);
416
  memcpy(filebuff + filesize, "LOCALCFG", 8);
417
  filesize += 8;
417
  filesize += 8;
418
 
418
 
419
  /* write the buffer to file */
419
  /* write the buffer to file */
420
  fd = fopen(fname, "wb");
420
  fd = fopen(fname, "wb");
421
  if (fd == NULL) return(-1);
421
  if (fd == NULL) return(-1);
422
  fwrite(filebuff, 1, filesize, fd);
422
  fwrite(filebuff, 1, filesize, fd);
423
  fclose(fd);
423
  fclose(fd);
424
 
424
 
425
  return(0);
425
  return(0);
426
}
426
}
427
 
427