-
Notifications
You must be signed in to change notification settings - Fork 2
/
cnf_lite.c
150 lines (131 loc) · 4.9 KB
/
cnf_lite.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#define NEWLIB_PORT_AWARE
#include <io_common.h>
#include "cnf_lite.h"
// Function prototypes.
static int get_CNF_string(char **CNF_p_p, char **name_p_p, char **value_p_p);
static int file_exists(const char *file)
{
int fd, result;
if ((fd = open(file, O_RDONLY)) >= 0) {
result = 1;
close(fd);
} else
result = 0;
return result;
}
//________________ From uLaunchELF ______________________
//---------------------------------------------------------------------------
// get_CNF_string is the main CNF parser called for each CNF variable in a
// CNF file. Input and output data is handled via its pointer parameters.
// The return value flags 'false' when no variable is found. (normal at EOF)
//---------------------------------------------------------------------------
static int get_CNF_string(char **CNF_p_p, char **name_p_p, char **value_p_p)
{
char *np, *vp, *tp = *CNF_p_p;
start_line:
while ((*tp <= ' ') && (*tp > '\0'))
tp += 1; // Skip leading whitespace, if any
if (*tp == '\0')
return 0; // but exit at EOF
np = tp; // Current pos is potential name
if (*tp < 'A') // but may be a comment line
{ // We must skip a comment line
while ((*tp != '\r') && (*tp != '\n') && (*tp > '\0'))
tp += 1; // Seek line end
goto start_line; // Go back to try next line
}
while ((*tp >= 'A') || ((*tp >= '0') && (*tp <= '9')))
tp += 1; // Seek name end
if (*tp == '\0')
return 0; // but exit at EOF
while ((*tp <= ' ') && (*tp > '\0'))
*tp++ = '\0'; // zero&skip post-name whitespace
if (*tp != '=')
return 0; // exit (syntax error) if '=' missing
*tp++ = '\0'; // zero '=' (possibly terminating name)
while ((*tp <= ' ') && (*tp > '\0') // Skip pre-value whitespace, if any
&& (*tp != '\r') && (*tp != '\n') // but do not pass the end of the line
&& (*tp != '\7') // allow ctrl-G (BEL) in value
)
tp += 1;
if (*tp == '\0')
return 0; // but exit at EOF
vp = tp; // Current pos is potential value
while ((*tp != '\r') && (*tp != '\n') && (*tp != '\0'))
tp += 1; // Seek line end
if (*tp != '\0')
*tp++ = '\0'; // terminate value (passing if not EOF)
while ((*tp <= ' ') && (*tp > '\0'))
tp += 1; // Skip following whitespace, if any
*CNF_p_p = tp; // return new CNF file position
*name_p_p = np; // return found variable name
*value_p_p = vp; // return found variable value
return 1; // return control to caller
} // Ends get_CNF_string
//----------------------------------------------------------------
int Read_SYSTEM_CNF(char *boot_path, char *ver)
{
// Returns disc type : 0 = failed; 1 = PS1; 2 = PS2;
size_t CNF_size;
char *RAM_p, *CNF_p, *name, *value;
int fd = -1;
int Disc_Type = -1; // -1 = Internal : Not Tested;
// place 3 question mark in ver string
strcpy(ver, "???");
fd = open("cdrom0:\\SYSTEM.CNF;1", O_RDONLY);
if (fd < 0) {
failed_load:
if (Disc_Type == -1) {
// Test PS1 special cases
if (file_exists("cdrom0:\\PSXMYST\\MYST.CCS;1")) {
strcpy(boot_path, "SLPS_000.24");
Disc_Type = 1;
} else if (file_exists("cdrom0:\\CDROM\\LASTPHOT\\ALL_C.NBN;1")) {
strcpy(boot_path, "SLPS_000.65");
Disc_Type = 1;
} else if (file_exists("cdrom0:\\PSX.EXE;1")) {
// place 3 question mark in pathname
strcpy(boot_path, "???");
Disc_Type = 1;
}
}
if (Disc_Type == -1)
Disc_Type = 0;
return Disc_Type;
} // This point is only reached after succefully opening CNF
Disc_Type = 0;
CNF_size = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
RAM_p = (char *)malloc(CNF_size);
CNF_p = RAM_p;
if (CNF_p == NULL) {
close(fd);
goto failed_load;
}
read(fd, CNF_p, CNF_size); // Read CNF as one long string
close(fd);
CNF_p[CNF_size] = '\0'; // Terminate the CNF string
strcpy(boot_path, "???"); // place 3 question mark in boot path
while (get_CNF_string(&CNF_p, &name, &value)) {
// A variable was found, now we dispose of its value.
if (!strcmp(name, "BOOT2")) { // check for BOOT2 entry
strcpy(boot_path, value);
Disc_Type = 2; // If found, PS2 disc type
break;
}
if (!strcmp(name, "BOOT")) { // check for BOOT entry
strcpy(boot_path, value);
Disc_Type = 1; // If found, PS1 disc type
continue;
}
if (!strcmp(name, "VER")) { // check for VER entry
strcpy(ver, value);
continue;
}
} // ends for
free(RAM_p);
return Disc_Type;
}