-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnetconfig.cpp
More file actions
155 lines (135 loc) · 4.96 KB
/
netconfig.cpp
File metadata and controls
155 lines (135 loc) · 4.96 KB
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
151
152
153
154
#include <windows.h>
#include <stdio.h>
#include "netconfig.h"
/* Add an entry to a comfiguration file. This function is only useful for
* temporary entries, since configuration files cannot be saved. This is used
* only as an internal procedure. */
CFGString* CFGAddEntry(CFGFile* cf)
{
cf->numncs++;
cf->ncs = (CFGString*)realloc(cf->ncs,sizeof(CFGString) * cf->numncs);
if (!cf->ncs) return NULL;
memset(&cf->ncs[cf->numncs - 1],0,sizeof(CFGString));
return &cf->ncs[cf->numncs - 1];
}
/* Load a configuration file. The function fails if the file doesn't exist or something. */
CFGFile* CFGLoadFile(char* filename)
{
/* open the file first */
FILE* f = fopen(filename,"rt");
if (!f) return NULL;
CFGFile* cf = (CFGFile*)malloc(sizeof(CFGFile));
if (!cf)
{
fclose(f);
return NULL;
}
memset(cf,0,sizeof(CFGFile));
/* loop over all lines in the file; max line length: 0x400 chars */
char line[0x400];
int x,y,length;
CFGString* ts;
while (fgets(line,0x400,f))
{
/* eliminate all nonstandard characters */
while (line[0] & 0x80) strcpy(line,&line[1]);
/* end the line at the first \r, \n, or # (for comments) */
for (x = 0; line[x]; x++) if ((line[x] == '#') || (line[x] == '\r') || (line[x] == '\n')) break;
line[x] = 0;
length = x;
/* find last non-whitespace character at the end of the line */
for (x--; x >= 0; x--) if ((line[x] != ' ') && (line[x] != '\t')) break;
if (x < 0) continue; /* line is all whitespace: skip it */
line[x + 1] = 0; /* delete whitespace at the end */
length = x + 1;
/* create a new entry and fill it in */
ts = CFGAddEntry(cf);
if (!ts)
{
/* error! clean up and return NULL */
CFGCloseFile(cf);
fclose(f);
return NULL;
}
/* fill in the name (until the first whitespace) */
for (x = 0; (line[x] != 0) && (line[x] != ' ') && (line[x] != '\t'); x++) ts->name[x] = line[x];
ts->name[x] = 0;
/* skip all whitespace until the value and fill it in */
for (; (line[x] == ' ') || (line[x] == '\t'); x++);
for (y = 0; line[x] != 0; x++, y++) ts->valueA[y] = ts->valueW[y] = line[x];
}
/* close the file and return */
fclose(f);
return cf;
}
/* free memory associated with a CFGFile */
void CFGCloseFile(CFGFile* cf)
{
free(cf->ncs);
free(cf);
}
/* parses a number in decimal (or hexadecimal, if prefixed with 0x (case-insensitive)) */
long CFGParseNumber(const char* str)
{
long number;
if ((str[0] == '0') && ((str[1] == 'x') || (str[1] == 'X'))) sscanf(&str[2],"%lx",&number);
else if ((str[0] == '0') && ((str[1] == 'o') || (str[1] == 'O'))) sscanf(&str[2],"%lo",&number);
else sscanf(str,"%ld",&number);
return number;
}
/* returns 1 if there's an entry with the given name, 0 otherwise. */
bool CFGIsValuePresent(CFGFile* cf,char* name)
{
DWORD x;
for (x = 0; x < cf->numncs; x++) if (!strcmp(name,cf->ncs[x].name)) return 1;
return 0;
}
/* returns the number represented by the specified name. if the name does not exist,
* this function returns 0. therefore, it is NOT SAFE to use this without CFGIsValuePresent(). */
long CFGGetNumber(CFGFile* cf,char* name)
{
char* str = CFGGetStringA(cf,name);
if (!str) return 0;
return CFGParseNumber(str);
}
/* returns the ANSI representation of the string represented by name, or NULL if it's nonexistant */
char* CFGGetStringA(CFGFile* cf,char* name)
{
DWORD x;
for (x = 0; x < cf->numncs; x++) if (!strcmp(name,cf->ncs[x].name)) return cf->ncs[x].valueA;
return NULL;
}
/* returns the ANSI representation of the string represented by name, or "[not found]" if it's nonexistant */
char* CFGGetStringSafeA(CFGFile* cf,char* name)
{
DWORD x;
for (x = 0; x < cf->numncs; x++) if (!strcmp(name,cf->ncs[x].name)) return cf->ncs[x].valueA;
return "[not found]";
}
/* returns the Unicode representation of the string represented by name, or NULL if it's nonexistant */
wchar_t* CFGGetStringW(CFGFile* cf,char* name)
{
DWORD x;
for (x = 0; x < cf->numncs; x++) if (!strcmp(name,cf->ncs[x].name)) return cf->ncs[x].valueW;
return NULL;
}
/* returns the Unicode representation of the string represented by name, or "[not found]" if it's nonexistant */
wchar_t* CFGGetStringSafeW(CFGFile* cf,char* name)
{
DWORD x;
for (x = 0; x < cf->numncs; x++) if (!strcmp(name,cf->ncs[x].name)) return cf->ncs[x].valueW;
return L"[not found]";
}
/* Enumerates each value in the specified CFGFile, calling a CFGEnumRoutine for each one.
* See CFGEnumRoutine in netconfig.h for mor information. */
bool CFGEnumValues(CFGFile* cf,CFGEnumRoutine func,long param)
{
unsigned int x,y;
for (x = 0; x < cf->numncs; )
{
y = func(cf,cf->ncs[x].name,cf->ncs[x].valueA,cf->ncs[x].valueW,param);
if (y) x += y;
else return 0;
}
return 1;
}