2 Copyright 2004-2005 Chris Tallon
3 Copyright 2004-2005 University Of Bradford
5 This file is part of VOMP.
7 VOMP 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.
12 VOMP 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.
17 You should have received a copy of the GNU General Public License
18 along with VOMP; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 int Config::init(char* takeFileName)
32 if (initted) return 1;
34 pthread_mutex_init(&fileLock, NULL);
36 if (strlen(takeFileName) > (MAX_FILENAME_LENGTH - 1))
38 printf("Config error: Config filename too long\n");
42 strcpy(fileName, takeFileName);
43 file = fopen(fileName, "r");
46 file = fopen(fileName, "w");
49 printf("Config error: Could not access config file\n");
60 int Config::shutdown()
62 if (!initted) return 1;
64 pthread_mutex_lock(&fileLock);
66 pthread_mutex_unlock(&fileLock);
67 pthread_mutex_destroy(&fileLock);
72 int Config::openFile()
74 if (!initted) return 0;
75 if (pthread_mutex_lock(&fileLock))
77 printf("Config error: Could not get lock\n");
82 printf("Config error: Initted 0 after lock\n");
83 pthread_mutex_unlock(&fileLock);
87 file = fopen(fileName, "r");
90 printf("Config error: Could not open config file\n");
91 pthread_mutex_unlock(&fileLock);
97 void Config::closeFile()
103 pthread_mutex_unlock(&fileLock);
106 int Config::readLine()
108 if (!initted || !file) { printf("1\n"); return 0; }
109 if (!fgets(buffer, BUFFER_LENGTH-1, file)) { printf("2\n"); return 0; }
110 lastLineLength = strlen(buffer);
111 printf("buffer before trim: '%s'\n", buffer);
113 printf("buffer after trim: '%s'\n", buffer);
119 FILE* Config::copyToHere(long position)
121 strcpy(fileNameTemp, "/tmp/configXXXXXX");
122 int newFileDes = mkstemp(fileNameTemp);
123 FILE* newFile = fdopen(newFileDes, "w");
125 if (!newFile) return NULL;
130 while (newPos < position)
132 fgets(buffer, BUFFER_LENGTH-1, file);
133 fputs(buffer, newFile);
134 newPos += strlen(buffer);
139 int Config::copyRest(FILE* newFile)
143 while(fgets(buffer, BUFFER_LENGTH-1, file))
145 fputs(buffer, newFile);
153 if (newFile) rename(fileNameTemp, fileName);
155 pthread_mutex_unlock(&fileLock);
159 int Config::deleteValue(char* section, char* key)
161 if (!initted) return 0;
162 if (!openFile()) return 0;
164 if (!findSection(section))
167 printf("Config error: Section %s not found\n", section);
173 printf("Config error: Key %s not found\n", key);
177 FILE* newFile = copyToHere(ftell(file) - lastLineLength);
178 fgets(buffer, BUFFER_LENGTH-1, file);
180 return copyRest(newFile);
183 int Config::setValueLong(char* section, char* key, long newValue)
186 sprintf(longBuffer, "%li", newValue);
187 return setValueString(section, key, longBuffer);
190 int Config::setValueLongLong(char* section, char* key, long long newValue)
193 sprintf(longBuffer, "%lli", newValue);
194 return setValueString(section, key, longBuffer);
197 int Config::setValueDouble(char* section, char* key, double newValue)
199 char doubleBuffer[50];
200 sprintf(doubleBuffer, "%f", newValue);
201 return setValueString(section, key, doubleBuffer);
204 int Config::setValueString(char* section, char* key, char* newValue)
206 if (!initted) return 0;
207 if (!openFile()) return 0;
209 if (findSection(section))
213 FILE* newFile = copyToHere(ftell(file) - lastLineLength);
217 printf("Config error: Could not write temp config file\n");
221 fgets(buffer, BUFFER_LENGTH-1, file);
222 fprintf(newFile, "%s = %s\n", key, newValue);
223 return copyRest(newFile);
228 findSection(section);
229 FILE* newFile = copyToHere(ftell(file));
233 printf("Config error: Could not write temp config file\n");
237 fprintf(newFile, "%s = %s\n", key, newValue);
238 return copyRest(newFile);
244 fseek(file, 0, SEEK_END);
245 FILE* newFile = copyToHere(ftell(file));
249 printf("Config error: Could not write temp config file\n");
253 fprintf(newFile, "[%s]\n%s = %s\n", section, key, newValue);
254 return copyRest(newFile);
258 char* Config::getSectionKeyNames(char* section, int& numberOfReturns, int& allKeysSize)
262 char* allKeys = NULL;
263 int allKeysIndex = 0;
267 if (!initted) return NULL;
268 if (!openFile()) return NULL;
269 if (!findSection(section)) return NULL;
271 char foundKey[BUFFER_LENGTH];
275 // Is this line a section header? if so, exit
276 if ((buffer[0] == '[') && (buffer[strlen(buffer)-1] == ']')) break;
278 equalspos = strstr(buffer, "=");
279 if (!equalspos) continue; // if there is no = then it's not a key
280 memcpy(foundKey, buffer, equalspos-buffer);
281 foundKey[equalspos-buffer] = '\0';
283 keyLength = strlen(foundKey);
284 allKeysSize += keyLength + 1;
285 allKeys = (char*)realloc(allKeys, allKeysSize);
286 memcpy(&allKeys[allKeysIndex], foundKey, keyLength);
287 allKeysIndex += keyLength;
288 allKeys[allKeysIndex] = '\0';
300 int Config::findSection(char* section)
302 if (!initted || !file) return 0;
303 if (strlen(section) > (BUFFER_LENGTH-2))
305 printf("Config error: Section given exceeds max length\n");
309 char toFind[BUFFER_LENGTH];
312 strcat(toFind, section);
317 printf("to find '%s' this line '%s'\n", toFind, buffer);
318 if (!strcmp(toFind, buffer)) return 1;
323 int Config::findKey(char* key)
325 if (!initted || !file) return 0;
327 if (strlen(key) > (BUFFER_LENGTH-1))
329 printf("Config error: Key given exceeds max length\n");
333 char prepForTest[BUFFER_LENGTH];
335 // do a rough search first, this could match substrings that we don't want
338 // Is this line a section header? if so, exit
339 if ((buffer[0] == '[') && (buffer[strlen(buffer)-1] == ']')) return 0;
340 if (strstr(buffer, key))
342 // rough search found match
343 char* equalspos = strstr(buffer, "=");
344 if (!equalspos) continue;
345 memcpy(prepForTest, buffer, equalspos-buffer);
346 prepForTest[equalspos-buffer] = '\0';
349 if (!strcmp(key, prepForTest))
351 // in buffer, set all up to equals to space, then trim!
352 for(char* curPos = buffer; curPos <= equalspos; curPos++)
364 char* Config::getValueString(char* section, char* key)
366 if (!initted) return NULL;
367 if (!openFile()) return NULL;
369 if (!findSection(section))
372 printf("Config error: Section %s not found\n", section);
378 printf("Config error: Key %s not found\n", key);
382 char* returnString = new char[strlen(buffer)+1];
383 strcpy(returnString, buffer);
390 long Config::getValueLong(char* section, char* key, int* failure)
393 if (!initted) return 0;
394 if (!openFile()) return 0;
396 if (!findSection(section))
399 printf("Config error: Section %s not found\n", section);
405 printf("Config error: Key %s not found\n", key);
411 long retVal = strtol(buffer, &check, 10);
412 if ((retVal == 0) && (check == buffer)) *failure = 1;
418 long long Config::getValueLongLong(char* section, char* key, int* failure)
421 if (!initted) return 0;
422 if (!openFile()) return 0;
424 if (!findSection(section))
427 printf("Config error: Section %s not found\n", section);
433 printf("Config error: Key %s not found\n", key);
439 long long retVal = strtoll(buffer, &check, 10);
440 if ((retVal == 0) && (check == buffer)) *failure = 1;
446 double Config::getValueDouble(char* section, char* key, int* failure)
449 if (!initted) return 0;
450 if (!openFile()) return 0;
452 if (!findSection(section))
455 printf("Config error: Section %s not found\n", section);
461 printf("Config error: Key %s not found\n", key);
468 double retVal = strtod(buffer, &check);
469 if ((retVal == 0) && (check == buffer)) *failure = 1;
478 void Config::trim(char* str)
480 int pos, len, start, end;
484 for(pos = 0; pos < len; pos++)
486 if ((str[pos] == '#') || (str[pos] == ';'))
488 // Mod. If #/; is at start of line ok. Else, if it is after a space, ok.
490 if ((pos == 0) || (isspace(str[pos - 1])))
504 while(isspace(str[start])) start++;
505 while(isspace(str[end-1]))
514 for(pos = start; pos < end; pos++) str[pos - start] = str[pos];
515 str[end - start] = '\0';