Files
KiTTY/kitty_store.c

757 lines
21 KiB
C

#include <limits.h>
#include "kitty_store.h"
#include "kitty_commun.h"
#include "kitty_tools.h"
#ifndef snewn
#define snewn(n, type) ((type *)safemalloc((n), sizeof(type)))
#endif
#ifndef sfree
#define sfree safefree
#endif
void debug_log( const char *fmt, ... ) ;
void DelDir( const char * directory ) ;
BOOL RegDelTree (HKEY hKeyRoot, LPCTSTR lpSubKey) ;
void CleanFolderName( char * folder ) ;
char * GetConfigDirectory( void ) ;
int GetReadOnlyFlag(void) ;
char * ltoa (long int __val, char *__s, int __radix) ;
char * itoa (int __val, char *__s, int __radix) ;
const char *win_strerror(int error) ;
char seedpath[2 * MAX_PATH + 10] = "\0";
char sesspath[2 * MAX_PATH] = "\0";
char initialsesspath[2 * MAX_PATH] = "\0";
char sshkpath[2 * MAX_PATH] = "\0";
char jumplistpath[2 * MAX_PATH] = "\0";
char oldpath[2 * MAX_PATH] = "\0";
char sessionsuffix[16] = "\0";
char keysuffix[16] = "\0";
static const char hex[16] = "0123456789ABCDEF";
void fatal_error(const char *p, ...) { exit(0) ; }
/*
void *safemalloc(size_t n, size_t size) {
void *p;
if (n > INT_MAX / size) {
p = NULL;
} else {
size *= n;
if (size == 0) size = 1;
#ifdef MINEFIELD
p = minefield_c_malloc(size);
#else
p = malloc(size);
#endif
}
if (!p)
fatal_error("out of memory");
return p;
}
void safefree(void *ptr)
{
if (ptr) {
#ifdef MINEFIELD
minefield_c_free(ptr);
#else
free(ptr);
#endif
}
}
*/
void SetHostKeyExtension( const char* ext ) {
char * buffer ;
buffer = (char*)malloc(strlen(ext)+2);
if( ext[0]!='.' ) { strcpy( buffer, "." ) ; } else { strcpy( buffer, "" ) ; }
strcat( buffer, ext ) ;
while( buffer[strlen(buffer)-1]==' ' ) { buffer[strlen(buffer)-1] = '\0' ; }
if( strlen(buffer)>15 ) { buffer[15]='\0' ; }
strcpy( keysuffix, buffer ) ;
free( buffer ) ;
}
/* JK: my generic function for simplyfing error reporting */
DWORD errorShow(const char* pcErrText, const char* pcErrParam) {
HWND hwRodic;
DWORD erChyba;
char pcBuf[16];
char* pcHlaska = snewn((pcErrParam?strlen(pcErrParam):0) + strlen(pcErrText) + 256, char);
erChyba = GetLastError();
ltoa(erChyba, pcBuf, 10);
strcpy(pcHlaska, "Error: ");
strcat(pcHlaska, pcErrText);
strcat(pcHlaska, "\n");
strcat(pcHlaska, "Directory: ");
char currpath[2*MAX_PATH];
GetCurrentDirectory( (MAX_PATH*2), currpath);
strcat(pcHlaska, currpath);
strcat(pcHlaska, "\n");
if (pcErrParam) {
strcat(pcHlaska, pcErrParam);
strcat(pcHlaska, "\n");
}
strcat(pcHlaska, "Error code: ");
strcat(pcHlaska, pcBuf);
/* JK: get parent-window and show */
hwRodic = GetActiveWindow();
if (hwRodic != NULL) { hwRodic = GetLastActivePopup(hwRodic);}
if (MessageBox(hwRodic, pcHlaska, "Error", MB_OK|MB_APPLMODAL|MB_ICONEXCLAMATION) == 0) {
/* JK: this is really bad -> just ignore */
sfree(pcHlaska);
return 0;
}
//MessageBox(GetActiveWindow(),pcHlaska, "Error", MB_OK|MB_APPLMODAL|MB_ICONEXCLAMATION) ;
sfree(pcHlaska);
return erChyba;
};
/* JK: pack string for use as filename - pack < > : " / \ | */
void packstr(const char *in, char *out) {
EMERGENCY_INIT
while (*in) {
EMERGENCY_BREAK
if (*in == '<' || *in == '>' || *in == ':' || *in == '"' ||
*in == '/' || *in == '|') {
*out++ = '%';
*out++ = hex[((unsigned char) *in) >> 4];
*out++ = hex[((unsigned char) *in) & 15];
} else
*out++ = *in;
in++;
}
*out = '\0';
return;
}
/*
* JK: create directory if specified as dir1\dir2\dir3 and dir1|2 doesn't exists
* handle if part of path already exists
*/
int createPath(char* dir) {
char *p;
if( GetReadOnlyFlag() ) { return 1 ; }
p = strrchr(dir, '\\');
if (p == NULL) {
/* what if it already exists */
if (!SetCurrentDirectory(dir)) {
CreateDirectory(dir, NULL);
return SetCurrentDirectory(dir);
}
return 1;
}
*p = '\0';
if( !createPath(dir) ) { MessageBox(NULL,"Unable to create directory !","Error",MB_OK|MB_ICONERROR) ; }
*p = '\\';
++p;
/* what if it already exists */
if (!SetCurrentDirectory(dir)) {
CreateDirectory(p, NULL);
return SetCurrentDirectory(p) ;
}
return 1;
}
/*
* JK: join path pcMain.pcSuf solving extra cases to pcDest
* expecting - pcMain as path from WinAPI ::GetCurrentDirectory()/GetModuleFileName()
* - pcSuf as user input path from config (at least MAX_PATH long)
*/
char* joinPath(char* pcDest, char* pcMain, char* pcSuf) {
char* pcBuf = snewn(MAX_PATH+1, char);
/* at first ExpandEnvironmentStrings */
if (0 == ExpandEnvironmentStrings(pcSuf, pcBuf, MAX_PATH)) {
/* JK: failure -> revert back - but it ussualy won't work, so report error to user! */
errorShow("Unable to ExpandEnvironmentStrings for session path", pcSuf);
strncpy(pcBuf, pcSuf, strlen(pcSuf));
}
/* now ExpandEnvironmentStringsForUser - only on win2000Pro and above */
/* It's much more tricky than I've expected, so it's ToDo */
/*
static HMODULE userenv_module = NULL;
typedef BOOL (WINAPI *p_ExpandESforUser_t) (HANDLE, LPCTSTR, LPTSTR, DWORD);
static p_ExpandESforUser_t p_ExpandESforUser = NULL;
HMODULE userenv_module = LoadLibrary("USERENV.DLL");
if (userenv_module) {
p_ExpandESforUser = (p_ExpandESforUser_t) GetProcAddress(shell32_module, "ExpandEnvironmentStringsForUserA");
if (p_ExpandESforUser) {
TOKEN_IMPERSONATE
if (0 == (p_ExpandESforUser(NULL, pcSuf, pcBuf, MAX_PATH))) {
*//* JK: failure -> revert back - but it ussualy won't work, so report error to user! *//*
errorShow("Unable to ExpandEnvironmentStringsForUser for session path", pcBuf);
strncpy(pcSuf, pcBuf, strlen(pcSuf));
}
}
}*/
/* expand done, resutl in pcBuf */
if ((*pcBuf == '/') || (*pcBuf == '\\')) {
/* everything ok */
strcpy(pcDest, pcMain);
strcat(pcDest, pcBuf);
}
else {
if (*(pcBuf+1) == ':') {
/* absolute path */
strcpy(pcDest, pcBuf);
}
else {
/* some weird relative path - add '\' */
strcpy(pcDest, pcMain);
strcat(pcDest, "\\");
strcat(pcDest, pcBuf);
}
}
sfree(pcBuf);
return pcDest;
}
/*
* JK: init path variables from config or otherwise
* as of 1.5 GetModuleFileName solves our currentDirectory problem
*/
int loadPath() {
if( *sesspath != '\0') { return 0 ; }
char *fileCont = NULL;
DWORD fileSize;
DWORD bytesRead;
char *p = NULL;
char *p2 = NULL;
HANDLE hFile ;
char* puttypath = snewn( (MAX_PATH*2), char);
/* JK: save path/curdir */
GetCurrentDirectory( (MAX_PATH*2), oldpath);
/* JK: try curdir for putty.conf first */
hFile = CreateFile("putty.conf",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
/* JK: there is a putty.conf in curdir - use it and use curdir as puttypath */
GetCurrentDirectory( (MAX_PATH*2), puttypath);
CloseHandle(hFile);
} else {
/* JK: get where putty.exe is */
if (GetModuleFileName(NULL, puttypath, (MAX_PATH*2)) != 0)
{
p = strrchr(puttypath, '\\');
if (p)
{
*p = '\0';
}
SetCurrentDirectory(puttypath);
}
else GetCurrentDirectory( (MAX_PATH*2), puttypath);
}
/* JK: set default values - if there is a config file, it will be overwitten */
if( GetConfigDirectory() != NULL ) { // Cas ou defini un autre repertoire de configuration
strcpy(sesspath, GetConfigDirectory());
strcat(sesspath, "\\Sessions");
strcpy(initialsesspath,sesspath);
strcpy(sshkpath, GetConfigDirectory());
strcat(sshkpath, "\\SshHostKeys");
strcpy(jumplistpath, GetConfigDirectory());
strcat(jumplistpath, "\\Jumplist");
strcpy(seedpath, GetConfigDirectory());
strcat(seedpath, "\\putty.rnd");
}
else {
strcpy(sesspath, puttypath);
strcat(sesspath, "\\Sessions");
strcpy(initialsesspath,sesspath);
strcpy(sshkpath, puttypath);
strcat(sshkpath, "\\SshHostKeys");
strcpy(jumplistpath, puttypath);
strcat(jumplistpath, "\\Jumplist");
strcpy(seedpath, puttypath);
strcat(seedpath, "\\putty.rnd");
}
hFile = CreateFile("putty.conf",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
/* Test Sessions directory */
if(get_param("INIFILE")==SAVEMODE_DIR)
if( !existdirectory(sesspath) ) {
if( !MakeDir(sesspath) ) {
MessageBox( NULL, "Unable to create sessions directory !", "Error", MB_OK|MB_ICONERROR ) ;
}
}
/* JK: now we can pre-clean-up */
SetCurrentDirectory(oldpath);
if (hFile != INVALID_HANDLE_VALUE) {
fileSize = GetFileSize(hFile, NULL);
fileCont = snewn(fileSize+16, char);
if (!ReadFile(hFile, fileCont, fileSize, &bytesRead, NULL))
{
errorShow("Unable to read configuration file, falling back to defaults", NULL);
/* JK: default values are already there and clean-up at end */
}
else {
/* JK: parse conf file to path variables */
*(fileCont+fileSize+1) = '\0';
*(fileCont+fileSize) = '\n';
p = fileCont;
EMERGENCY_INIT
while (p) {
EMERGENCY_BREAK
if (*p == ';') { /* JK: comment -> skip line */
p = strchr(p, '\n');
++p;
continue;
}
p2 = strchr(p, '=');
if (!p2) break;
*p2 = '\0';
++p2;
if (!strcmp(p, "Sessions")) {
p = strchr(p2, '\n');
*p = '\0';
joinPath(sesspath, puttypath, p2);
p2 = sesspath+strlen(sesspath)-1;
while ((*p2 == ' ')||(*p2 == '\n')||(*p2 == '\r')||(*p2 == '\t')) --p2;
*(p2+1) = '\0';
}
else if (!strcmp(p, "SshHostKeys")) {
p = strchr(p2, '\n');
*p = '\0';
joinPath(sshkpath, puttypath, p2);
p2 = sshkpath+strlen(sshkpath)-1;
while ((*p2 == ' ')||(*p2 == '\n')||(*p2 == '\r')||(*p2 == '\t')) --p2;
*(p2+1) = '\0';
}
else if (!strcmp(p, "Jumplist")) {
p = strchr(p2, '\n');
*p = '\0';
joinPath(jumplistpath, puttypath, p2);
p2 = jumplistpath+strlen(jumplistpath)-1;
while ((*p2 == ' ')||(*p2 == '\n')||(*p2 == '\r')||(*p2 == '\t')) --p2;
*(p2+1) = '\0';
}
else if (!strcmp(p, "seedfile")) {
p = strchr(p2, '\n');
*p = '\0';
joinPath(seedpath, puttypath, p2);
p2 = seedpath+strlen(seedpath)-1;
while ((*p2 == ' ')||(*p2 == '\n')||(*p2 == '\r')||(*p2 == '\t')) --p2;
*(p2+1) = '\0';
}
else if (!strcmp(p, "sessionsuffix")) {
p = strchr(p2, '\n');
*p = '\0';
strcpy(sessionsuffix, p2);
p2 = sessionsuffix+strlen(sessionsuffix)-1;
while ((*p2 == ' ')||(*p2 == '\n')||(*p2 == '\r')||(*p2 == '\t')) --p2;
*(p2+1) = '\0';
}
else if (!strcmp(p, "keysuffix")) {
p = strchr(p2, '\n');
*p = '\0';
strcpy(keysuffix, p2);
p2 = keysuffix+strlen(keysuffix)-1;
while ((*p2 == ' ')||(*p2 == '\n')||(*p2 == '\r')||(*p2 == '\t')) --p2;
*(p2+1) = '\0';
}
++p;
}
}
CloseHandle(hFile);
sfree(fileCont);
}
/* else - INVALID_HANDLE {
* JK: unable to read conf file - probably doesn't exists
* we won't create one, user wants putty light, just fall back to defaults
* and defaults are already there
}*/
sfree(puttypath);
return 1;
}
char * SetSessPath( const char * dec ) {
int i ;
char *pst ;
if( !strcmp(dec,"..") ) {
if( strcmp(sesspath, initialsesspath) ) {
i=strlen(sesspath)-1 ;
while( (sesspath[i]!='\\') && (i>0) ) i--;
sesspath[i]='\0';
}
} else {
strcat( sesspath, "\\" ) ;
strcat( sesspath, dec ) ;
}
CleanFolderName( sesspath ) ;
pst = sesspath+strlen(initialsesspath ) ;
while( pst[0]=='\\' ) pst++ ;
return pst ;
}
char * SetInitialSessPath( void ) { return strcpy( sesspath, initialsesspath ) ; }
char * GetSessPath( void ) {
return sesspath ;
}
bool SessPathIsInitial( void ) {
if( !strcmp( sesspath, initialsesspath ) ) { return true ; }
else { return false ; }
}
bool IsThereDefaultSessionFile( void ) {
bool t=false;
char *buf = (char*)malloc(strlen(sesspath)+strlen("Default%%20Settings")+strlen(FileExtension)+2) ;
if( !strcmp(FileExtension,"") ) {
sprintf(buf,"%s\\Default%%20Settings%s",sesspath,FileExtension) ;
} else {
sprintf(buf,"%s\\Default%%20Settings",sesspath) ;
}
t = existfile(buf) ;
free(buf) ;
return t;
}
int CreateFolderInPath( const char * d ) {
char buf[MAX_PATH] ;
int res = 0 ;
sprintf( buf, "%s\\%s", sesspath, d ) ;
res = createPath( buf ) ;
if( !res ) { MessageBox(NULL,"Unable to create directory", "Error", MB_OK|MB_ICONERROR); }
return res ;
}
void SaveDumpPortableConfig( FILE * fp ) {
fprintf( fp, "seedpath=%s\n", seedpath ) ;
fprintf( fp, "sesspath=%s\n", sesspath ) ;
fprintf( fp, "initialsesspath=%s\n", initialsesspath ) ;
fprintf( fp, "sshkpath=%s\n", sshkpath ) ;
fprintf( fp, "jumplistpath=%s\n", jumplistpath ) ;
fprintf( fp, "oldpath=%s\n", oldpath ) ;
fprintf( fp, "sessionsuffix=%s\n", sessionsuffix ) ;
fprintf( fp, "keysuffix=%s\n", keysuffix ) ;
}
HSettingsItem SettingsNewItem( const char * name, const char * value ) {
if( name==NULL ) return NULL ;
HSettingsItem NewItem = malloc( sizeof( SettingsItem ) ) ;
NewItem->pNext = NULL ;
NewItem->pPrevious = NULL ;
NewItem->name = malloc( strlen(name) + 1 ) ; strcpy( NewItem->name, name ) ;
if( value == NULL ) {
NewItem->value = NULL ;
} else {
NewItem->value = malloc( strlen(value) + 1 ) ; strcpy( NewItem->value, value ) ;
}
return NewItem ;
}
HSettingsList SettingsInit() {
HSettingsList list = (HSettingsList)malloc( sizeof(SettingsList) ) ;
list->filename = NULL ;
list->num = 0 ;
list->first = NULL ;
list->last = NULL ;
return list ;
}
HSettingsList PortableSettings ;
void SettingsDelItem( HSettingsList list, const char * key ) {
if( list != NULL ) {
HSettingsItem current = list->first ;
while( current != NULL ) {
if( current->name != NULL ) {
if( !strcmp( current->name, key ) ) {
if( current->value != NULL ) { free( current->value ) ; current->value = NULL ; }
free( current->name ) ; current->name = NULL ;
if( current->pPrevious != NULL ) {
current->pPrevious->pNext = current->pNext ;
} else {
list->first = current->pNext ;
}
if( current->pNext != NULL ) {
current->pNext->pPrevious = current->pPrevious ;
} else {
list->last = current->pPrevious ;
}
}
}
current = current->pNext ;
}
}
}
void SettingsAddItem( HSettingsList list, const char * name, const char * value ) {
if( list!=NULL ) {
HSettingsItem NewItem = SettingsNewItem( name, value ) ;
if( NewItem != NULL ) {
HSettingsItem current = list->last ;
if( current == NULL ) {
list->first = NewItem ;
NewItem->pNext = NULL ;
NewItem->pPrevious = NULL ;
} else {
SettingsDelItem( list, name ) ;
current->pNext = NewItem ;
NewItem->pPrevious = current ;
}
list->last = NewItem ;
list->num = list->num + 1 ;
}
}
}
void SettingsFreeItem( HSettingsItem item ) {
if( item != NULL ) {
//debug_log("%s=%s\n",item->name,item->value);
if( item->value != NULL ) { free( item->value ) ; item->value = NULL ; } // POURQUOI CA PLANTE ???
if( item->name != NULL ) { free( item->name ) ; item->name = NULL ; }
item->pPrevious = NULL ;
item->pNext = NULL ;
free( item ) ;
}
}
void SettingsFree( HSettingsList list ) {
if( list != NULL ) {
HSettingsItem current = list->first, next ;
if( current != NULL ) {
while( current != NULL ) {
next = current->pNext ;
SettingsFreeItem( current ) ;
current = next ;
}
}
list->first = NULL ;
list->last = NULL ;
if( list->filename != NULL ) { free( list->filename ) ; list->filename = NULL ; }
list->num = 0 ;
free( list ) ;
}
}
char * SettingsKey( HSettingsList list, const char * key ) {
if( list != NULL ) {
HSettingsItem current = list->first ;
while( current != NULL ) {
if( current->name != NULL ) {
if( !strcmp( current->name, key ) ) return current->value ;
}
current = current->pNext ;
}
}
return NULL ;
}
char * SettingsKey_str( HSettingsList list, const char * key ) {
if( list != NULL ) {
HSettingsItem current = list->first ;
while( current != NULL ) {
if( current->name != NULL ) {
if( !strcmp( current->name, key ) ) {
return dupstr( current->value ) ;
}
}
current = current->pNext ;
}
}
return NULL ;
}
int SettingsKey_int( HSettingsList list, const char * key, const int defvalue ) {
if( list != NULL ) {
HSettingsItem current = list->first ;
while( current != NULL ) {
if( current->name != NULL ) {
if( !strcmp( current->name, key ) ) {
return atoi( current->value ) ;
}
}
current = current->pNext ;
}
}
return defvalue ;
}
void SettingsLoad( HSettingsList list, const char * filename ) {
FILE * fp ;
char *buffer;
int p ;
//debug_log("filename=%s|\n",filename); int i=0;
if( (fp=fopen(filename,"rb")) != NULL ) {
list->filename = (char*) malloc( strlen(filename)+1 ) ; strcpy( list->filename, filename ) ;
buffer = (char*)malloc(4096*sizeof(char)) ;
while( fgets(buffer,4096,fp) != NULL ) {
//debug_log("\nline %05d[%d]: %s|\n",++i,strlen(buffer),buffer);
while( buffer[strlen(buffer)-1]!='\n' ) {
buffer = realloc( buffer, strlen(buffer) + 4096 ) ;
if( fgets( buffer+strlen(buffer), 4096, fp ) == NULL ) { break ; }
//debug_log("\nline %05d[%d]: %s|\n",++i,strlen(buffer),buffer);
}
char *name, *value, *value2 ;
while( (buffer[strlen(buffer)-1]=='\n') || (buffer[strlen(buffer)-1]=='\r') ) buffer[strlen(buffer)-1] = '\0' ;
//debug_log("line %05d[%d]: %s|\n",i,strlen(buffer),buffer);
//debug_log("\t-2=%c -3=%c\n",buffer[strlen(buffer)-2],buffer[strlen(buffer)-3]);
while( buffer[strlen(buffer)-1]!='\\' ) {
//debug_log("ici\n");
while( buffer[strlen(buffer)-1]=='\r' ) { buffer[strlen(buffer)+1]='\0' ; buffer[strlen(buffer)-1]='\\' ; buffer[strlen(buffer)] = 'r' ; }
while( buffer[strlen(buffer)-1]=='\n' ) { buffer[strlen(buffer)+1]='\0' ; buffer[strlen(buffer)-1]='\\' ; buffer[strlen(buffer)] = 'n' ; }
if( fgets( buffer+strlen(buffer), 4096, fp ) == NULL ) { break ; }
while( (buffer[strlen(buffer)-1]=='\n') || (buffer[strlen(buffer)-1]=='\r') ) buffer[strlen(buffer)-1] = '\0' ;
}
//debug_log("line %05d[%d]: %s|\n",i,strlen(buffer),buffer);
while( (buffer[strlen(buffer)-1]=='\n') || (buffer[strlen(buffer)-1]=='\r') ) buffer[strlen(buffer)-1] = '\0' ;
//debug_log("line %05d[%d]: %s|\n",i,strlen(buffer),buffer);
if( buffer[strlen(buffer)-1] != '\\' ) { strcat( buffer, "\\" ) ; }
//debug_log("line %05d[%d]: %s|\n",i,strlen(buffer),buffer);
p = poss( "\\", buffer ) ;
if( p>1 ) {
name = (char*) malloc( p+1 ) ;
memcpy( name, buffer, p-1 ) ; name[p-1]='\0' ;
value = (char*) malloc( strlen(buffer)-p+1 ) ;
strcpy( value, buffer+p ) ;
value[strlen(value)-1]='\0' ;
//debug_log("line %05d: %s|%s|\n",i,name,value);
value2 = (char*) malloc( strlen(value)+1 ) ;
unmungestr( value, value2, strlen(value)+1 ) ;
//debug_log("line %05d: %s|%s|%s|\n",i,name,value,value2);
SettingsAddItem( list, name, value2 ) ;
free( value2 ) ;
free( value ) ;
free( name ) ;
}
}
free(buffer) ;
fclose(fp );
} else {
//if( strcmp(filename,"Default%20Settings") ) MessageBox(NULL,"Unable to open session file", "Error", MB_OK);
errorShow( "Unable to read session file", filename ) ;
}
}
void SettingsSave( HSettingsList list, const char * filename ) {
FILE * fp ;
char buffer[4096] ;
if( (fp=fopen(filename,"wb")) != NULL ) {
if( list != NULL ) {
HSettingsItem current = list->first ;
while( current != NULL ) {
if( current->name != NULL ) {
if( current->value == NULL ) {
sprintf( buffer, "%s\\\\\n", current->value ) ;
} else {
char * p = (char*) malloc( 3*strlen(current->value)+1 ) ;
mungestr( current->value, p ) ;
sprintf( buffer, "%s\\%s\\\n", current->name, p ) ;
free( p ) ;
}
fputs( buffer, fp ) ;
fflush( fp ) ;
}
current = current->pNext ;
}
}
fclose(fp);
} else {
errorShow( "Unable to write session file", filename ) ;
}
}
/*
void SettingsPrint( HSettingsList list ) {
if( list != NULL ) {
debug_log( "->filename=%s\n", list->filename ) ;
debug_log( "->num=%d\n", list->num ) ;
debug_log( "->first=%ld\n", list->first ) ;
debug_log( "->last=%ld\n", list->last ) ;
HSettingsItem current = list->first ;
while( current != NULL ) {
if( current->name !=NULL ) {
if( current->value !=NULL ) { debug_log( "%s=%s\n", current->name, current->value ) ;
} else { debug_log( "%s=NULL\n", current->name ) ;
}
}
debug_log(" current=%ld\n", current );
if( current->pPrevious == NULL ) { debug_log( " previous=NULL\n" ) ; }
else { debug_log( " previous=%ld\n", current->pPrevious ) ; }
if( current->pNext == NULL ) { debug_log( " next=NULL\n" ) ; }
else { debug_log( " next=%ld\n", current->pNext ) ; }
current = current->pNext ;
}
}
debug_log( "NULL\n\n" ) ;
}
void SettingTest( void ) {
PortableSettings = SettingsInit() ;
SettingsPrint( PortableSettings ) ;
SettingsLoad( PortableSettings, "Ken" ) ;
SettingsPrint( PortableSettings ) ;
SettingsFree( PortableSettings ) ;
debug_log( "FIN\n\n" ) ;
}
*/
bool ReadPortableValue(const char *buffer, const char * name, char * value, const int maxlen) {
bool test = false ;
if( (buffer==NULL) || (name==NULL) ) { return false ; }
if( (strlen(buffer)==0) || (strlen(name)==0) ) { return false ; }
if( maxlen<=0 ) { return false ; }
char *b = (char*)malloc(strlen(name)+2), *pst ;
sprintf(b,"%s\\",name) ;
if( strstr(buffer,b)==buffer ) {
pst = (char*)buffer + strlen(b) ;
test = true ;
value[0]='\0';
if( strlen(pst)>1 )
if( (strlen(pst)<=maxlen) && (pst[strlen(pst)-2]=='\\') ) {
memcpy( value, pst, strlen(pst)-2 ) ;
value[strlen(pst)-2] = '\0' ;
}
unmungestr( value, value, MAX_VALUE_NAME ) ;
}
free(b) ;
return test ;
}