mirror of
https://github.com/glest/glest-source.git
synced 2025-08-30 11:19:48 +02:00
- updated line endings to unix style characters to fix Bug #3085838
This commit is contained in:
@@ -1,177 +1,177 @@
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpAccount.c - User account handling
|
||||
*
|
||||
* User account management is based on username, password and
|
||||
* access-rights. An account can be created with the function
|
||||
* ftpCreateAccount.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief User account data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name[MAXLEN_USERNAME]; ///< user name
|
||||
char passw[MAXLEN_PASSWORD]; ///< password of the account
|
||||
char ftpRoot[MAX_PATH_LEN]; ///< root path of the user account on the server
|
||||
int ftpRootLen; ///< length of ftpRoot
|
||||
int accRights; ///< access rights of a account
|
||||
|
||||
}ftpUserAccount_S;
|
||||
|
||||
/**
|
||||
* @brief Array which holds all registered user accounts
|
||||
*/
|
||||
LOCAL ftpUserAccount_S ftpUsers[MAX_USERS];
|
||||
|
||||
/**
|
||||
* @brief Creates a new user account
|
||||
*
|
||||
* The translated path depends on the current working directory of the
|
||||
* session and the root path of the session. In addition the path will
|
||||
* be normalized.
|
||||
* @todo normalize root and check if normalized path really exists
|
||||
*
|
||||
* @param name user name
|
||||
* @param passw account password
|
||||
* @param root root directory of the account
|
||||
* @param acc access rights, can be any combination of the following flags:
|
||||
* - FTP_ACC_RD read access
|
||||
* - FTP_ACC_WR write access
|
||||
* - FTP_ACC_LS access to directory listing
|
||||
* - FTP_ACC_DIR changing of working dir allowed
|
||||
*
|
||||
* @return 0 on success; -1 if MAX_USERS is reached
|
||||
*/
|
||||
int ftpCreateAccount(const char* name, const char* passw, const char* root, int acc)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ftpFindAccount(name); // check if account already exists
|
||||
if(n > 0)
|
||||
{
|
||||
ftpUsers[n - 1].name[0] = '\0'; // delete account
|
||||
}
|
||||
|
||||
for(n = 0; n < MAX_USERS; n++)
|
||||
{
|
||||
if(ftpUsers[n].name[0] == '\0')
|
||||
{
|
||||
strncpy(ftpUsers[n].name, name, MAXLEN_USERNAME);
|
||||
strncpy(ftpUsers[n].passw, passw, MAXLEN_PASSWORD);
|
||||
strncpy(ftpUsers[n].ftpRoot, root, MAX_PATH_LEN);
|
||||
ftpUsers[n].ftpRootLen = strlen(root);
|
||||
ftpUsers[n].accRights = acc;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the account id for a user name
|
||||
*
|
||||
* The function searches ftpUsers for the passed user name.
|
||||
* The returned account id is the index + 1 in ftpUsers.
|
||||
*
|
||||
* @param name user name
|
||||
*
|
||||
* @return 0 if user is not found; 1 to MAX_USERS+1 if user is found
|
||||
*/
|
||||
int ftpFindAccount(const char* name)
|
||||
{
|
||||
int n;
|
||||
|
||||
if(name[0] != '\0')
|
||||
for(n = 0; n < MAX_USERS; n++)
|
||||
if(!strncmp(ftpUsers[n].name, name, MAXLEN_USERNAME))
|
||||
return n + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the password of a user account
|
||||
*
|
||||
* Compares the passed password to the saved password in ftpUsers
|
||||
*
|
||||
* @param userId user account id
|
||||
* @param passw password
|
||||
*
|
||||
* @return - 0: password is correct
|
||||
* - -1: invalid user account id
|
||||
* - else: incorrect password
|
||||
*/
|
||||
int ftpCheckPassword(int userId, const char* passw)
|
||||
{
|
||||
if(!userId)
|
||||
return -1;
|
||||
else if(ftpUsers[userId - 1].passw[0] == '\0')
|
||||
return 0;
|
||||
else
|
||||
return strncmp(ftpUsers[userId - 1].passw, passw, MAXLEN_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the account has the needed rights
|
||||
*
|
||||
* Compares the passed access rights to the saved rights in ftpUsers
|
||||
*
|
||||
* @param userId user account id
|
||||
* @param accRights needed access rights
|
||||
*
|
||||
* @return - 0: the needed access rights are fulfilled
|
||||
* - -1: invalid user account id
|
||||
*/
|
||||
int ftpCheckAccRights(int userId, int accRights)
|
||||
{
|
||||
if(!userId)
|
||||
return -1;
|
||||
|
||||
if((ftpUsers[userId - 1].accRights & accRights) == accRights)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the root directory of a account
|
||||
*
|
||||
* @param userId user account id
|
||||
* @param len length of the returned path
|
||||
*
|
||||
* @return root directory name or NULL if the user account id is invalid
|
||||
*/
|
||||
const char* ftpGetRoot(int userId, int* len)
|
||||
{
|
||||
if(!userId)
|
||||
return NULL;
|
||||
if(len)
|
||||
*len = ftpUsers[userId - 1].ftpRootLen;
|
||||
|
||||
return ftpUsers[userId - 1].ftpRoot;
|
||||
}
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpAccount.c - User account handling
|
||||
*
|
||||
* User account management is based on username, password and
|
||||
* access-rights. An account can be created with the function
|
||||
* ftpCreateAccount.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief User account data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name[MAXLEN_USERNAME]; ///< user name
|
||||
char passw[MAXLEN_PASSWORD]; ///< password of the account
|
||||
char ftpRoot[MAX_PATH_LEN]; ///< root path of the user account on the server
|
||||
int ftpRootLen; ///< length of ftpRoot
|
||||
int accRights; ///< access rights of a account
|
||||
|
||||
}ftpUserAccount_S;
|
||||
|
||||
/**
|
||||
* @brief Array which holds all registered user accounts
|
||||
*/
|
||||
LOCAL ftpUserAccount_S ftpUsers[MAX_USERS];
|
||||
|
||||
/**
|
||||
* @brief Creates a new user account
|
||||
*
|
||||
* The translated path depends on the current working directory of the
|
||||
* session and the root path of the session. In addition the path will
|
||||
* be normalized.
|
||||
* @todo normalize root and check if normalized path really exists
|
||||
*
|
||||
* @param name user name
|
||||
* @param passw account password
|
||||
* @param root root directory of the account
|
||||
* @param acc access rights, can be any combination of the following flags:
|
||||
* - FTP_ACC_RD read access
|
||||
* - FTP_ACC_WR write access
|
||||
* - FTP_ACC_LS access to directory listing
|
||||
* - FTP_ACC_DIR changing of working dir allowed
|
||||
*
|
||||
* @return 0 on success; -1 if MAX_USERS is reached
|
||||
*/
|
||||
int ftpCreateAccount(const char* name, const char* passw, const char* root, int acc)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ftpFindAccount(name); // check if account already exists
|
||||
if(n > 0)
|
||||
{
|
||||
ftpUsers[n - 1].name[0] = '\0'; // delete account
|
||||
}
|
||||
|
||||
for(n = 0; n < MAX_USERS; n++)
|
||||
{
|
||||
if(ftpUsers[n].name[0] == '\0')
|
||||
{
|
||||
strncpy(ftpUsers[n].name, name, MAXLEN_USERNAME);
|
||||
strncpy(ftpUsers[n].passw, passw, MAXLEN_PASSWORD);
|
||||
strncpy(ftpUsers[n].ftpRoot, root, MAX_PATH_LEN);
|
||||
ftpUsers[n].ftpRootLen = strlen(root);
|
||||
ftpUsers[n].accRights = acc;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the account id for a user name
|
||||
*
|
||||
* The function searches ftpUsers for the passed user name.
|
||||
* The returned account id is the index + 1 in ftpUsers.
|
||||
*
|
||||
* @param name user name
|
||||
*
|
||||
* @return 0 if user is not found; 1 to MAX_USERS+1 if user is found
|
||||
*/
|
||||
int ftpFindAccount(const char* name)
|
||||
{
|
||||
int n;
|
||||
|
||||
if(name[0] != '\0')
|
||||
for(n = 0; n < MAX_USERS; n++)
|
||||
if(!strncmp(ftpUsers[n].name, name, MAXLEN_USERNAME))
|
||||
return n + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks the password of a user account
|
||||
*
|
||||
* Compares the passed password to the saved password in ftpUsers
|
||||
*
|
||||
* @param userId user account id
|
||||
* @param passw password
|
||||
*
|
||||
* @return - 0: password is correct
|
||||
* - -1: invalid user account id
|
||||
* - else: incorrect password
|
||||
*/
|
||||
int ftpCheckPassword(int userId, const char* passw)
|
||||
{
|
||||
if(!userId)
|
||||
return -1;
|
||||
else if(ftpUsers[userId - 1].passw[0] == '\0')
|
||||
return 0;
|
||||
else
|
||||
return strncmp(ftpUsers[userId - 1].passw, passw, MAXLEN_PASSWORD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the account has the needed rights
|
||||
*
|
||||
* Compares the passed access rights to the saved rights in ftpUsers
|
||||
*
|
||||
* @param userId user account id
|
||||
* @param accRights needed access rights
|
||||
*
|
||||
* @return - 0: the needed access rights are fulfilled
|
||||
* - -1: invalid user account id
|
||||
*/
|
||||
int ftpCheckAccRights(int userId, int accRights)
|
||||
{
|
||||
if(!userId)
|
||||
return -1;
|
||||
|
||||
if((ftpUsers[userId - 1].accRights & accRights) == accRights)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the root directory of a account
|
||||
*
|
||||
* @param userId user account id
|
||||
* @param len length of the returned path
|
||||
*
|
||||
* @return root directory name or NULL if the user account id is invalid
|
||||
*/
|
||||
const char* ftpGetRoot(int userId, int* len)
|
||||
{
|
||||
if(!userId)
|
||||
return NULL;
|
||||
if(len)
|
||||
*len = ftpUsers[userId - 1].ftpRootLen;
|
||||
|
||||
return ftpUsers[userId - 1].ftpRoot;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,171 +1,171 @@
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpLib.c - Global helper functions
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
#include "ftpIfc.h"
|
||||
|
||||
/**
|
||||
* @brief Removes the trailing slash of a directory path
|
||||
*
|
||||
* @param path directory path
|
||||
*
|
||||
* @return len of path
|
||||
*/
|
||||
int ftpRemoveTrailingSlash(char* path)
|
||||
{
|
||||
int len = strlen(path);
|
||||
|
||||
if(len > 1)
|
||||
{
|
||||
len--;
|
||||
if(path[len] == '/')
|
||||
path[len] = '\0';
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes double slashes in a path
|
||||
*
|
||||
* e. g. "//a//b//c" will be converted to "a/b/c"
|
||||
*
|
||||
* @param path directory path
|
||||
*/
|
||||
void ftpRemoveDoubleSlash(char* path)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = path;
|
||||
|
||||
while(*p != '\0')
|
||||
{
|
||||
if((p[0] == '/') && (p[1] == '/'))
|
||||
ftpStrcpy(p, &p[1]);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Merges multiple path strings
|
||||
*
|
||||
* The function catenates all passed strings to a new string and assures that
|
||||
* the result does not exceed MAX_PATH_LEN. The last parameter has to be
|
||||
* NULL.
|
||||
* @todo Not all embedded environments support variadic functions, or they are
|
||||
* too expensive.
|
||||
*
|
||||
* @param dest user name
|
||||
*
|
||||
* @return Pointer to dest
|
||||
*/
|
||||
char* ftpMergePaths(char* dest, ...)
|
||||
{
|
||||
const char* src;
|
||||
char* dst = dest;
|
||||
int len = 0;
|
||||
va_list args;
|
||||
|
||||
va_start(args, dest);
|
||||
|
||||
while((src = va_arg(args, const char*)))
|
||||
{
|
||||
while((*src != '\0') && (len < MAX_PATH_LEN-1))
|
||||
{
|
||||
*dst++ = *src++;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
va_end(args);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine the unix-time
|
||||
*
|
||||
* The function reads the clock from the target-layer and converts it to the
|
||||
* unix-time. The code is taken from http://de.wikipedia.org/wiki/Unixzeit
|
||||
*
|
||||
* @return seconds since 1. Januar 1970 00:00
|
||||
*/
|
||||
uint32_t ftpGetUnixTime(void)
|
||||
{
|
||||
ftpTime_S t;
|
||||
uint32_t unixTime = 0;
|
||||
int j;
|
||||
|
||||
ftpGetLocalTime(&t);
|
||||
|
||||
for(j=1970;j<t.year;j++) // leap years
|
||||
{
|
||||
if(j%4==0 && (j%100!=0 || j%400==0))
|
||||
unixTime+=(366*24*60*60);
|
||||
else
|
||||
unixTime+=(365*24*60*60);
|
||||
}
|
||||
for(j=1;j<t.month;j++) // days per month 31/30/29/28
|
||||
{
|
||||
if(j==1 || j==3 || j==5 || j==7 || j==8 || j==10 || j==12)
|
||||
unixTime+=(31*24*60*60); // months with 31 days
|
||||
if(j==4 || j==6 || j==9 || j==11)
|
||||
unixTime+=(30*24*60*60); // months with 30 days
|
||||
if( (j==2) && (t.year%4==0 && (t.year%100!=0 || t.year%400==0)) )
|
||||
unixTime+=(29*24*60*60);
|
||||
else
|
||||
unixTime+=(28*24*60*60);
|
||||
}
|
||||
unixTime+=((t.day-1)*24*60*60);
|
||||
unixTime+=(t.hour*60*60);
|
||||
unixTime+=t.minute*60;
|
||||
unixTime+=t.second;
|
||||
|
||||
return unixTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief copy a string
|
||||
*
|
||||
* The reason why feathery has its own strcpy is that in some cases src is
|
||||
* part of dest and src > dest. Because ANSI-C explicitly declares that case
|
||||
* as undefined our strcpy guarantees to copy from lower to higher
|
||||
* addresses.
|
||||
*
|
||||
* @param dest destination string
|
||||
* @param src Null-terminated source string
|
||||
*
|
||||
* @return destination string
|
||||
*/
|
||||
char *ftpStrcpy(char *dest, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
|
||||
while (*d++ = *s++);
|
||||
return dest;
|
||||
}
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpLib.c - Global helper functions
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
#include "ftpIfc.h"
|
||||
|
||||
/**
|
||||
* @brief Removes the trailing slash of a directory path
|
||||
*
|
||||
* @param path directory path
|
||||
*
|
||||
* @return len of path
|
||||
*/
|
||||
int ftpRemoveTrailingSlash(char* path)
|
||||
{
|
||||
int len = strlen(path);
|
||||
|
||||
if(len > 1)
|
||||
{
|
||||
len--;
|
||||
if(path[len] == '/')
|
||||
path[len] = '\0';
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes double slashes in a path
|
||||
*
|
||||
* e. g. "//a//b//c" will be converted to "a/b/c"
|
||||
*
|
||||
* @param path directory path
|
||||
*/
|
||||
void ftpRemoveDoubleSlash(char* path)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = path;
|
||||
|
||||
while(*p != '\0')
|
||||
{
|
||||
if((p[0] == '/') && (p[1] == '/'))
|
||||
ftpStrcpy(p, &p[1]);
|
||||
else
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Merges multiple path strings
|
||||
*
|
||||
* The function catenates all passed strings to a new string and assures that
|
||||
* the result does not exceed MAX_PATH_LEN. The last parameter has to be
|
||||
* NULL.
|
||||
* @todo Not all embedded environments support variadic functions, or they are
|
||||
* too expensive.
|
||||
*
|
||||
* @param dest user name
|
||||
*
|
||||
* @return Pointer to dest
|
||||
*/
|
||||
char* ftpMergePaths(char* dest, ...)
|
||||
{
|
||||
const char* src;
|
||||
char* dst = dest;
|
||||
int len = 0;
|
||||
va_list args;
|
||||
|
||||
va_start(args, dest);
|
||||
|
||||
while((src = va_arg(args, const char*)))
|
||||
{
|
||||
while((*src != '\0') && (len < MAX_PATH_LEN-1))
|
||||
{
|
||||
*dst++ = *src++;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
va_end(args);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determine the unix-time
|
||||
*
|
||||
* The function reads the clock from the target-layer and converts it to the
|
||||
* unix-time. The code is taken from http://de.wikipedia.org/wiki/Unixzeit
|
||||
*
|
||||
* @return seconds since 1. Januar 1970 00:00
|
||||
*/
|
||||
uint32_t ftpGetUnixTime(void)
|
||||
{
|
||||
ftpTime_S t;
|
||||
uint32_t unixTime = 0;
|
||||
int j;
|
||||
|
||||
ftpGetLocalTime(&t);
|
||||
|
||||
for(j=1970;j<t.year;j++) // leap years
|
||||
{
|
||||
if(j%4==0 && (j%100!=0 || j%400==0))
|
||||
unixTime+=(366*24*60*60);
|
||||
else
|
||||
unixTime+=(365*24*60*60);
|
||||
}
|
||||
for(j=1;j<t.month;j++) // days per month 31/30/29/28
|
||||
{
|
||||
if(j==1 || j==3 || j==5 || j==7 || j==8 || j==10 || j==12)
|
||||
unixTime+=(31*24*60*60); // months with 31 days
|
||||
if(j==4 || j==6 || j==9 || j==11)
|
||||
unixTime+=(30*24*60*60); // months with 30 days
|
||||
if( (j==2) && (t.year%4==0 && (t.year%100!=0 || t.year%400==0)) )
|
||||
unixTime+=(29*24*60*60);
|
||||
else
|
||||
unixTime+=(28*24*60*60);
|
||||
}
|
||||
unixTime+=((t.day-1)*24*60*60);
|
||||
unixTime+=(t.hour*60*60);
|
||||
unixTime+=t.minute*60;
|
||||
unixTime+=t.second;
|
||||
|
||||
return unixTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief copy a string
|
||||
*
|
||||
* The reason why feathery has its own strcpy is that in some cases src is
|
||||
* part of dest and src > dest. Because ANSI-C explicitly declares that case
|
||||
* as undefined our strcpy guarantees to copy from lower to higher
|
||||
* addresses.
|
||||
*
|
||||
* @param dest destination string
|
||||
* @param src Null-terminated source string
|
||||
*
|
||||
* @return destination string
|
||||
*/
|
||||
char *ftpStrcpy(char *dest, const char *src)
|
||||
{
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
|
||||
while (*d++ = *s++);
|
||||
return dest;
|
||||
}
|
||||
|
@@ -1,66 +1,66 @@
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpMessages.c - FTP-Server messages
|
||||
*
|
||||
* This Module defines all message-strings the servers sends to
|
||||
* clients. If someone needs to translate the server user interface
|
||||
* to a different language this is the only file to be touched.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
const char ftpMsg000[] = "Data connection error";
|
||||
const char ftpMsg001[] = "File error";
|
||||
const char ftpMsg002[] = "File send OK";
|
||||
const char ftpMsg003[] = "File received OK";
|
||||
const char ftpMsg004[] = "Please specify the password";
|
||||
const char ftpMsg005[] = "Login successful";
|
||||
const char ftpMsg006[] = "Login failed";
|
||||
const char ftpMsg007[] = "PORT command successful. Consider using PASV.";
|
||||
const char ftpMsg008[] = "NOOP command successful";
|
||||
const char ftpMsg009[] = "Goodby";
|
||||
const char ftpMsg010[] = "Here comes the listing";
|
||||
const char ftpMsg011[] = "Could not establish data connection.";
|
||||
const char ftpMsg012[] = "Could not establish passive data connection.";
|
||||
const char ftpMsg013[] = "Directory send OK";
|
||||
const char ftpMsg014[] = "Sending file...";
|
||||
const char ftpMsg015[] = "Could not open file.";
|
||||
const char ftpMsg016[] = "Receiving file...";
|
||||
const char ftpMsg018[] = "Could not delete file";
|
||||
const char ftpMsg019[] = "File deleted";
|
||||
const char ftpMsg020[] = "Could create directory";
|
||||
const char ftpMsg021[] = "Directory created";
|
||||
const char ftpMsg022[] = "Could remove directory";
|
||||
const char ftpMsg023[] = "Directory removed";
|
||||
const char ftpMsg024[] = "Directory successfully changed";
|
||||
const char ftpMsg025[] = "Failed to change directory";
|
||||
const char ftpMsg026[] = "Switching to binary mode";
|
||||
const char ftpMsg027[] = "Switching to ascii mode";
|
||||
const char ftpMsg028[] = "Unknown type-code";
|
||||
const char ftpMsg029[] = "Entering passive mode";
|
||||
const char ftpMsg030[] = "Switching to file mode";
|
||||
const char ftpMsg031[] = "Only file mode supported";
|
||||
const char ftpMsg032[] = "Invalid path";
|
||||
const char ftpMsg033[] = "Please login with USER and PASS.";
|
||||
const char ftpMsg034[] = "Permission denied.";
|
||||
const char ftpMsg035[] = "Line too long.";
|
||||
const char ftpMsg036[] = "Timeout.";
|
||||
const char ftpMsg037[] = "Hi";
|
||||
const char ftpMsg038[] = "Could not open directory.";
|
||||
const char ftpMsg039[] = "Could not read directory.";
|
||||
const char ftpMsg040[] = "Aborted.";
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpMessages.c - FTP-Server messages
|
||||
*
|
||||
* This Module defines all message-strings the servers sends to
|
||||
* clients. If someone needs to translate the server user interface
|
||||
* to a different language this is the only file to be touched.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
const char ftpMsg000[] = "Data connection error";
|
||||
const char ftpMsg001[] = "File error";
|
||||
const char ftpMsg002[] = "File send OK";
|
||||
const char ftpMsg003[] = "File received OK";
|
||||
const char ftpMsg004[] = "Please specify the password";
|
||||
const char ftpMsg005[] = "Login successful";
|
||||
const char ftpMsg006[] = "Login failed";
|
||||
const char ftpMsg007[] = "PORT command successful. Consider using PASV.";
|
||||
const char ftpMsg008[] = "NOOP command successful";
|
||||
const char ftpMsg009[] = "Goodby";
|
||||
const char ftpMsg010[] = "Here comes the listing";
|
||||
const char ftpMsg011[] = "Could not establish data connection.";
|
||||
const char ftpMsg012[] = "Could not establish passive data connection.";
|
||||
const char ftpMsg013[] = "Directory send OK";
|
||||
const char ftpMsg014[] = "Sending file...";
|
||||
const char ftpMsg015[] = "Could not open file.";
|
||||
const char ftpMsg016[] = "Receiving file...";
|
||||
const char ftpMsg018[] = "Could not delete file";
|
||||
const char ftpMsg019[] = "File deleted";
|
||||
const char ftpMsg020[] = "Could create directory";
|
||||
const char ftpMsg021[] = "Directory created";
|
||||
const char ftpMsg022[] = "Could remove directory";
|
||||
const char ftpMsg023[] = "Directory removed";
|
||||
const char ftpMsg024[] = "Directory successfully changed";
|
||||
const char ftpMsg025[] = "Failed to change directory";
|
||||
const char ftpMsg026[] = "Switching to binary mode";
|
||||
const char ftpMsg027[] = "Switching to ascii mode";
|
||||
const char ftpMsg028[] = "Unknown type-code";
|
||||
const char ftpMsg029[] = "Entering passive mode";
|
||||
const char ftpMsg030[] = "Switching to file mode";
|
||||
const char ftpMsg031[] = "Only file mode supported";
|
||||
const char ftpMsg032[] = "Invalid path";
|
||||
const char ftpMsg033[] = "Please login with USER and PASS.";
|
||||
const char ftpMsg034[] = "Permission denied.";
|
||||
const char ftpMsg035[] = "Line too long.";
|
||||
const char ftpMsg036[] = "Timeout.";
|
||||
const char ftpMsg037[] = "Hi";
|
||||
const char ftpMsg038[] = "Could not open directory.";
|
||||
const char ftpMsg039[] = "Could not read directory.";
|
||||
const char ftpMsg040[] = "Aborted.";
|
||||
|
@@ -1,50 +1,50 @@
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpRuntime.c - ftp-server runtime environment
|
||||
*
|
||||
* This is the central module of feathery. It defines all runtime functions
|
||||
* of feathery. That is startup, state, main-thread an shutdown.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
#include "ftpMessages.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief server-sockets that listens for incoming connections
|
||||
*/
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpRuntime.c - ftp-server runtime environment
|
||||
*
|
||||
* This is the central module of feathery. It defines all runtime functions
|
||||
* of feathery. That is startup, state, main-thread an shutdown.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
#include "ftpMessages.h"
|
||||
|
||||
|
||||
/**
|
||||
* @brief server-sockets that listens for incoming connections
|
||||
*/
|
||||
LOCAL socket_t server;
|
||||
LOCAL int serverListenPort;
|
||||
LOCAL int serverPassiveListenPort;
|
||||
//LOCAL socket_t serverPassivePort;
|
||||
|
||||
void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4) {
|
||||
//LOCAL socket_t serverPassivePort;
|
||||
|
||||
void ftpInit(ftpFindExternalFTPServerIpType cb1, ftpAddUPNPPortForwardType cb2, ftpRemoveUPNPPortForwardType cb3, ftpIsValidClientType cb4) {
|
||||
ftpFindExternalFTPServerIp = cb1;
|
||||
ftpAddUPNPPortForward = cb2;
|
||||
ftpRemoveUPNPPortForward = cb3;
|
||||
ftpIsValidClient = cb4;
|
||||
}
|
||||
ftpIsValidClient = cb4;
|
||||
}
|
||||
|
||||
int ftpGetListenPort()
|
||||
{
|
||||
@@ -60,227 +60,227 @@ int ftpGetPassivePort()
|
||||
//{
|
||||
// return serverPassivePort;
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief Initializes and starts the server
|
||||
*
|
||||
*
|
||||
* @return - 0: server started successfully
|
||||
* - -1: could not create server socket
|
||||
*/
|
||||
int ftpStart(int portNumber)
|
||||
|
||||
/**
|
||||
* @brief Initializes and starts the server
|
||||
*
|
||||
*
|
||||
* @return - 0: server started successfully
|
||||
* - -1: could not create server socket
|
||||
*/
|
||||
int ftpStart(int portNumber)
|
||||
{
|
||||
serverListenPort = portNumber;
|
||||
serverPassiveListenPort = portNumber + 1;
|
||||
serverPassiveListenPort = portNumber + 1;
|
||||
server = -1; // set server socket to invalid value
|
||||
//serverPassivePort = -1;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("Feathery FTP-Server\n");
|
||||
|
||||
ftpArchInit();
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("Creating server socket");
|
||||
|
||||
server = ftpCreateServerSocket(serverListenPort); // create main listener socket
|
||||
if(server < 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\terror\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\tok\n");
|
||||
if(VERBOSE_MODE_ENABLED) printf("Server successfully started\n");
|
||||
|
||||
//serverPassivePort = -1;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("Feathery FTP-Server\n");
|
||||
|
||||
ftpArchInit();
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("Creating server socket");
|
||||
|
||||
server = ftpCreateServerSocket(serverListenPort); // create main listener socket
|
||||
if(server < 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\terror\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\tok\n");
|
||||
if(VERBOSE_MODE_ENABLED) printf("Server successfully started\n");
|
||||
|
||||
ftpTrackSocket(server); // add socket to "watchlist"
|
||||
|
||||
|
||||
/*
|
||||
if(VERBOSE_MODE_ENABLED) printf("Creating server PASSIVE socket");
|
||||
|
||||
serverPassivePort = ftpCreateServerSocket(serverPassiveListenPort); // create main listener socket
|
||||
if(serverPassivePort < 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\tpassive port error\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\tok\n");
|
||||
if(VERBOSE_MODE_ENABLED) printf("Server passive port successfully started\n");
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if the server has something to do
|
||||
*
|
||||
* In order of avoid blocking of ftpExecute this function can be used to
|
||||
* determine if the server has something to do. You can call this function in
|
||||
* a loop and everytime it returns nonezero its time to call ftpExecute().
|
||||
* @todo implement me
|
||||
*
|
||||
* @return 0 noting to do; else server has received some data
|
||||
*/
|
||||
int ftpState(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Main server-thread
|
||||
*
|
||||
* Manages all client connections and active transmitions. In addtition
|
||||
* all received control-strings are dispatched to the command-module.
|
||||
* Note, the function blocks if there is nothing to do.
|
||||
*/
|
||||
int ftpExecute(void)
|
||||
{
|
||||
int processedWork=0;
|
||||
int n=0;
|
||||
int socksRdy=0;
|
||||
ftpSession_S *pSession=NULL;
|
||||
int sessionId=0;
|
||||
int activeJobs=0;
|
||||
int len;
|
||||
int bufLen;
|
||||
|
||||
activeJobs = ftpGetActiveTransCnt(); // are there any active transmitions?
|
||||
//for(n = 0; (activeJobs > 0) && (n < MAX_CONNECTIONS); n++)
|
||||
for(n = 0; n < MAX_CONNECTIONS; n++)
|
||||
{
|
||||
pSession = ftpGetSession(n);
|
||||
if(pSession->activeTrans.op) // has this session an active transmition?
|
||||
{
|
||||
processedWork = 1;
|
||||
ftpExecTransmission(n); // do the job
|
||||
activeJobs--;
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpGetActiveTransCnt()) // don't block if there's still something to do
|
||||
{
|
||||
socksRdy = ftpSelect(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if(VERBOSE_MODE_ENABLED) printf("ftpExecute calling blocking select\n");
|
||||
socksRdy = ftpSelect(FALSE);
|
||||
}
|
||||
|
||||
if(socksRdy > 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpExecute socksRdy = %d\n",socksRdy);
|
||||
if(VERBOSE_MODE_ENABLED) printf("Creating server PASSIVE socket");
|
||||
|
||||
processedWork = 1;
|
||||
if(ftpTestSocket(server)) // server listner-socket signaled?
|
||||
{
|
||||
socket_t clientSocket;
|
||||
ip_t remoteIP;
|
||||
port_t remotePort;
|
||||
|
||||
socksRdy--;
|
||||
clientSocket = ftpAcceptServerConnection(server, &remoteIP, &remotePort);
|
||||
if(clientSocket >= 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpExecute ftpAcceptServerConnection = %d\n",clientSocket);
|
||||
|
||||
sessionId = ftpOpenSession(clientSocket, remoteIP, remotePort);
|
||||
if(sessionId >= 0)
|
||||
{
|
||||
ftpTrackSocket(clientSocket);
|
||||
ftpSendMsg(MSG_NORMAL, sessionId, 220, ftpMsg037);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ERROR: Connection refused; Session limit reached, about to close socket = %d\n",clientSocket);
|
||||
|
||||
ftpUntrackSocket(clientSocket);
|
||||
ftpCloseSocket(&clientSocket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//socksRdy = ftpSelect(TRUE);
|
||||
for(n = 0; (socksRdy > 0) && (n < MAX_CONNECTIONS); n++)
|
||||
{
|
||||
pSession = ftpGetSession(n);
|
||||
if(pSession->open)
|
||||
{
|
||||
socket_t ctrlSocket = pSession->ctrlSocket;
|
||||
|
||||
if(ftpTestSocket(ctrlSocket))
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpExecute signaled socket = %d, session = %d\n",ctrlSocket,n);
|
||||
socksRdy--;
|
||||
bufLen = (LEN_RXBUF - pSession->rxBufWriteIdx);
|
||||
len = ftpReceive(ctrlSocket,
|
||||
&pSession->rxBuf[pSession->rxBufWriteIdx],
|
||||
bufLen);
|
||||
if(len <= 0) // has client shutdown the connection?
|
||||
{
|
||||
int errorNumber = getLastSocketError();
|
||||
const char *errText = getLastSocketErrorText(&errorNumber);
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpExecute ERROR ON RECEIVE session = %d for socket = %d, data len = %d index = %d, len = %d, error = %d [%s]\n",n,ctrlSocket,bufLen,pSession->rxBufWriteIdx,len,errorNumber,errText);
|
||||
|
||||
ftpUntrackSocket(ctrlSocket);
|
||||
ftpCloseSession(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSession->rxBufWriteIdx += len;
|
||||
ftpParseCmd(n);
|
||||
}
|
||||
}
|
||||
/// @bug Session-Timeout-Management doesn't work
|
||||
if((ftpGetUnixTime() - pSession->timeLastCmd) > SESSION_TIMEOUT)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("\nIn ftpExecute ERROR: SESSION TIMED OUT for socket = %d\n",ctrlSocket);
|
||||
|
||||
ftpSendMsg(MSG_NORMAL, n, 421, ftpMsg036);
|
||||
ftpUntrackSocket(ctrlSocket);
|
||||
ftpCloseSession(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
serverPassivePort = ftpCreateServerSocket(serverPassiveListenPort); // create main listener socket
|
||||
if(serverPassivePort < 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\tpassive port error\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return processedWork;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shut down the server
|
||||
*
|
||||
* Cuts all tcp-connections and frees all used resources.
|
||||
|
||||
* @return 0
|
||||
*/
|
||||
int ftpShutdown(void)
|
||||
{
|
||||
int n;
|
||||
if(VERBOSE_MODE_ENABLED) printf("About to Shutdown Feathery FTP-Server server [%d]\n",server);
|
||||
|
||||
ftpUntrackSocket(server);
|
||||
if(VERBOSE_MODE_ENABLED) printf("\t\tok\n");
|
||||
if(VERBOSE_MODE_ENABLED) printf("Server passive port successfully started\n");
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Checks if the server has something to do
|
||||
*
|
||||
* In order of avoid blocking of ftpExecute this function can be used to
|
||||
* determine if the server has something to do. You can call this function in
|
||||
* a loop and everytime it returns nonezero its time to call ftpExecute().
|
||||
* @todo implement me
|
||||
*
|
||||
* @return 0 noting to do; else server has received some data
|
||||
*/
|
||||
int ftpState(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Main server-thread
|
||||
*
|
||||
* Manages all client connections and active transmitions. In addtition
|
||||
* all received control-strings are dispatched to the command-module.
|
||||
* Note, the function blocks if there is nothing to do.
|
||||
*/
|
||||
int ftpExecute(void)
|
||||
{
|
||||
int processedWork=0;
|
||||
int n=0;
|
||||
int socksRdy=0;
|
||||
ftpSession_S *pSession=NULL;
|
||||
int sessionId=0;
|
||||
int activeJobs=0;
|
||||
int len;
|
||||
int bufLen;
|
||||
|
||||
activeJobs = ftpGetActiveTransCnt(); // are there any active transmitions?
|
||||
//for(n = 0; (activeJobs > 0) && (n < MAX_CONNECTIONS); n++)
|
||||
for(n = 0; n < MAX_CONNECTIONS; n++)
|
||||
{
|
||||
pSession = ftpGetSession(n);
|
||||
if(pSession->activeTrans.op) // has this session an active transmition?
|
||||
{
|
||||
processedWork = 1;
|
||||
ftpExecTransmission(n); // do the job
|
||||
activeJobs--;
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpGetActiveTransCnt()) // don't block if there's still something to do
|
||||
{
|
||||
socksRdy = ftpSelect(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if(VERBOSE_MODE_ENABLED) printf("ftpExecute calling blocking select\n");
|
||||
socksRdy = ftpSelect(FALSE);
|
||||
}
|
||||
|
||||
if(socksRdy > 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpExecute socksRdy = %d\n",socksRdy);
|
||||
|
||||
processedWork = 1;
|
||||
if(ftpTestSocket(server)) // server listner-socket signaled?
|
||||
{
|
||||
socket_t clientSocket;
|
||||
ip_t remoteIP;
|
||||
port_t remotePort;
|
||||
|
||||
socksRdy--;
|
||||
clientSocket = ftpAcceptServerConnection(server, &remoteIP, &remotePort);
|
||||
if(clientSocket >= 0)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpExecute ftpAcceptServerConnection = %d\n",clientSocket);
|
||||
|
||||
sessionId = ftpOpenSession(clientSocket, remoteIP, remotePort);
|
||||
if(sessionId >= 0)
|
||||
{
|
||||
ftpTrackSocket(clientSocket);
|
||||
ftpSendMsg(MSG_NORMAL, sessionId, 220, ftpMsg037);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ERROR: Connection refused; Session limit reached, about to close socket = %d\n",clientSocket);
|
||||
|
||||
ftpUntrackSocket(clientSocket);
|
||||
ftpCloseSocket(&clientSocket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//socksRdy = ftpSelect(TRUE);
|
||||
for(n = 0; (socksRdy > 0) && (n < MAX_CONNECTIONS); n++)
|
||||
{
|
||||
pSession = ftpGetSession(n);
|
||||
if(pSession->open)
|
||||
{
|
||||
socket_t ctrlSocket = pSession->ctrlSocket;
|
||||
|
||||
if(ftpTestSocket(ctrlSocket))
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpExecute signaled socket = %d, session = %d\n",ctrlSocket,n);
|
||||
socksRdy--;
|
||||
bufLen = (LEN_RXBUF - pSession->rxBufWriteIdx);
|
||||
len = ftpReceive(ctrlSocket,
|
||||
&pSession->rxBuf[pSession->rxBufWriteIdx],
|
||||
bufLen);
|
||||
if(len <= 0) // has client shutdown the connection?
|
||||
{
|
||||
int errorNumber = getLastSocketError();
|
||||
const char *errText = getLastSocketErrorText(&errorNumber);
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpExecute ERROR ON RECEIVE session = %d for socket = %d, data len = %d index = %d, len = %d, error = %d [%s]\n",n,ctrlSocket,bufLen,pSession->rxBufWriteIdx,len,errorNumber,errText);
|
||||
|
||||
ftpUntrackSocket(ctrlSocket);
|
||||
ftpCloseSession(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
pSession->rxBufWriteIdx += len;
|
||||
ftpParseCmd(n);
|
||||
}
|
||||
}
|
||||
/// @bug Session-Timeout-Management doesn't work
|
||||
if((ftpGetUnixTime() - pSession->timeLastCmd) > SESSION_TIMEOUT)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("\nIn ftpExecute ERROR: SESSION TIMED OUT for socket = %d\n",ctrlSocket);
|
||||
|
||||
ftpSendMsg(MSG_NORMAL, n, 421, ftpMsg036);
|
||||
ftpUntrackSocket(ctrlSocket);
|
||||
ftpCloseSession(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return processedWork;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Shut down the server
|
||||
*
|
||||
* Cuts all tcp-connections and frees all used resources.
|
||||
|
||||
* @return 0
|
||||
*/
|
||||
int ftpShutdown(void)
|
||||
{
|
||||
int n;
|
||||
if(VERBOSE_MODE_ENABLED) printf("About to Shutdown Feathery FTP-Server server [%d]\n",server);
|
||||
|
||||
ftpUntrackSocket(server);
|
||||
ftpCloseSocket(&server);
|
||||
//ftpCloseSocket(serverPassivePort);
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("About to Shutdown clients\n");
|
||||
|
||||
for(n = 0; n < MAX_CONNECTIONS; n++)
|
||||
{
|
||||
if(ftpGetSession(n)->open)
|
||||
{
|
||||
//ftpCloseSocket(serverPassivePort);
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("About to Shutdown clients\n");
|
||||
|
||||
for(n = 0; n < MAX_CONNECTIONS; n++)
|
||||
{
|
||||
if(ftpGetSession(n)->open)
|
||||
{
|
||||
ftpUntrackSocket(ftpGetSession(n)->ctrlSocket);
|
||||
}
|
||||
ftpCloseSession(n);
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("About to Shutdown stack\n");
|
||||
ftpArchCleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
ftpCloseSession(n);
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("About to Shutdown stack\n");
|
||||
ftpArchCleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1,38 +1,38 @@
|
||||
/* FEATHERY FTP-Server
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
* <https://sourceforge.net/projects/feathery>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/* FEATHERY FTP-Server
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
* <https://sourceforge.net/projects/feathery>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
|
||||
#include "ftpIfc.h"
|
||||
int main(void)
|
||||
{
|
||||
ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
ftpCreateAccount("nothing", "", "./", 0);
|
||||
ftpCreateAccount("reader", "", "./", FTP_ACC_RD);
|
||||
ftpCreateAccount("writer", "", "./", FTP_ACC_WR);
|
||||
ftpCreateAccount("lister", "", "./", FTP_ACC_LS);
|
||||
ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
|
||||
ftpStart();
|
||||
while(1)
|
||||
ftpExecute();
|
||||
ftpShutdown();
|
||||
|
||||
}
|
||||
|
||||
#include "ftpIfc.h"
|
||||
int main(void)
|
||||
{
|
||||
ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
ftpCreateAccount("nothing", "", "./", 0);
|
||||
ftpCreateAccount("reader", "", "./", FTP_ACC_RD);
|
||||
ftpCreateAccount("writer", "", "./", FTP_ACC_WR);
|
||||
ftpCreateAccount("lister", "", "./", FTP_ACC_LS);
|
||||
ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
|
||||
ftpStart();
|
||||
while(1)
|
||||
ftpExecute();
|
||||
ftpShutdown();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,370 +1,370 @@
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpSession.c - Session handling of connected clients
|
||||
*
|
||||
* A ftp session is a TCP connection between the server and a ftp client.
|
||||
* Each session has its own unique session id. The session id refers
|
||||
* (index in session[]) to a struct ftpSession_S which holds all
|
||||
* relevant data. The virtual chroot environment is also part of the
|
||||
* session management.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
|
||||
/**
|
||||
* @brief array that holds the data of all ftp sessions
|
||||
*
|
||||
* The index represents the session ID.
|
||||
*/
|
||||
LOCAL ftpSession_S sessions[MAX_CONNECTIONS];
|
||||
|
||||
/**
|
||||
* @brief number of active file or directory transmission
|
||||
*/
|
||||
LOCAL int actTransCnt;
|
||||
|
||||
/**
|
||||
* @brief Scratch-buffer for path manipulation
|
||||
*/
|
||||
LOCAL char pathScratchBuf[MAX_PATH_LEN];
|
||||
|
||||
|
||||
/**
|
||||
* @brief Opens a ftp session
|
||||
*
|
||||
* Searches in 'sessions' for an empty entry and inits the session data.
|
||||
* Call this function after accepting a tcp connection from a ftp client.
|
||||
*
|
||||
* @param ctrlSocket control socket which initiated the the ftp session
|
||||
* @param remoteIp IP address of the client
|
||||
* @param remotePort TCP-Port of the client
|
||||
*
|
||||
* @return session id or -1 if session limit is reached
|
||||
*/
|
||||
int ftpOpenSession(socket_t ctrlSocket, ip_t remoteIp, port_t remotePort)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < MAX_CONNECTIONS; n++)
|
||||
{
|
||||
if(!sessions[n].open)
|
||||
{
|
||||
sessions[n].open = TRUE;
|
||||
sessions[n].authenticated = FALSE;
|
||||
sessions[n].userId = 0;
|
||||
sessions[n].workingDir[0] = '\0';
|
||||
sessions[n].remoteIp = remoteIp;
|
||||
sessions[n].remotePort = remotePort;
|
||||
sessions[n].remoteDataPort = 0;
|
||||
sessions[n].passive = FALSE;
|
||||
sessions[n].binary = TRUE;
|
||||
sessions[n].timeLastCmd = ftpGetUnixTime();
|
||||
sessions[n].ctrlSocket = ctrlSocket;
|
||||
sessions[n].passiveDataSocket = -1;
|
||||
sessions[n].rxBufWriteIdx = 0;
|
||||
sessions[n].activeTrans.op = OP_NOP;
|
||||
sessions[n].activeTrans.fsHandle = NULL;
|
||||
sessions[n].activeTrans.dataSocket = -1;
|
||||
sessions[n].activeTrans.fileSize = 0;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpOpenSession started for ctrlSocket: %d\n",ctrlSocket);
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the current ftp session as 'authenticated'
|
||||
*
|
||||
* @param id Session id
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
int ftpAuthSession(int id)
|
||||
{
|
||||
sessions[id].authenticated = TRUE;
|
||||
strcpy(sessions[id].workingDir, "/");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes a ftp session
|
||||
*
|
||||
* Closes the TCP control connection and releases the session struct.
|
||||
*
|
||||
* @param id Session id
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
int ftpCloseSession(int id)
|
||||
/**
|
||||
* Feathery FTP-Server <https://sourceforge.net/projects/feathery>
|
||||
* Copyright (C) 2005-2010 Andreas Martin (andreas.martin@linuxmail.org)
|
||||
*
|
||||
* ftpSession.c - Session handling of connected clients
|
||||
*
|
||||
* A ftp session is a TCP connection between the server and a ftp client.
|
||||
* Each session has its own unique session id. The session id refers
|
||||
* (index in session[]) to a struct ftpSession_S which holds all
|
||||
* relevant data. The virtual chroot environment is also part of the
|
||||
* session management.
|
||||
*
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ftpTypes.h"
|
||||
#include "ftpConfig.h"
|
||||
#include "ftp.h"
|
||||
|
||||
/**
|
||||
* @brief array that holds the data of all ftp sessions
|
||||
*
|
||||
* The index represents the session ID.
|
||||
*/
|
||||
LOCAL ftpSession_S sessions[MAX_CONNECTIONS];
|
||||
|
||||
/**
|
||||
* @brief number of active file or directory transmission
|
||||
*/
|
||||
LOCAL int actTransCnt;
|
||||
|
||||
/**
|
||||
* @brief Scratch-buffer for path manipulation
|
||||
*/
|
||||
LOCAL char pathScratchBuf[MAX_PATH_LEN];
|
||||
|
||||
|
||||
/**
|
||||
* @brief Opens a ftp session
|
||||
*
|
||||
* Searches in 'sessions' for an empty entry and inits the session data.
|
||||
* Call this function after accepting a tcp connection from a ftp client.
|
||||
*
|
||||
* @param ctrlSocket control socket which initiated the the ftp session
|
||||
* @param remoteIp IP address of the client
|
||||
* @param remotePort TCP-Port of the client
|
||||
*
|
||||
* @return session id or -1 if session limit is reached
|
||||
*/
|
||||
int ftpOpenSession(socket_t ctrlSocket, ip_t remoteIp, port_t remotePort)
|
||||
{
|
||||
int n;
|
||||
for(n = 0; n < MAX_CONNECTIONS; n++)
|
||||
{
|
||||
if(!sessions[n].open)
|
||||
{
|
||||
sessions[n].open = TRUE;
|
||||
sessions[n].authenticated = FALSE;
|
||||
sessions[n].userId = 0;
|
||||
sessions[n].workingDir[0] = '\0';
|
||||
sessions[n].remoteIp = remoteIp;
|
||||
sessions[n].remotePort = remotePort;
|
||||
sessions[n].remoteDataPort = 0;
|
||||
sessions[n].passive = FALSE;
|
||||
sessions[n].binary = TRUE;
|
||||
sessions[n].timeLastCmd = ftpGetUnixTime();
|
||||
sessions[n].ctrlSocket = ctrlSocket;
|
||||
sessions[n].passiveDataSocket = -1;
|
||||
sessions[n].rxBufWriteIdx = 0;
|
||||
sessions[n].activeTrans.op = OP_NOP;
|
||||
sessions[n].activeTrans.fsHandle = NULL;
|
||||
sessions[n].activeTrans.dataSocket = -1;
|
||||
sessions[n].activeTrans.fileSize = 0;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpOpenSession started for ctrlSocket: %d\n",ctrlSocket);
|
||||
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Marks the current ftp session as 'authenticated'
|
||||
*
|
||||
* @param id Session id
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
int ftpAuthSession(int id)
|
||||
{
|
||||
sessions[id].authenticated = TRUE;
|
||||
strcpy(sessions[id].workingDir, "/");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes a ftp session
|
||||
*
|
||||
* Closes the TCP control connection and releases the session struct.
|
||||
*
|
||||
* @param id Session id
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
int ftpCloseSession(int id)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpCloseSession sessionId = %d, remote IP = %u, port = %d, ctrlSocket = %d\n",
|
||||
id, sessions[id].remoteIp, sessions[id].remoteFTPServerPassivePort,sessions[id].ctrlSocket);
|
||||
id, sessions[id].remoteIp, sessions[id].remoteFTPServerPassivePort,sessions[id].ctrlSocket);
|
||||
|
||||
if(ftpFindExternalFTPServerIp != NULL && ftpFindExternalFTPServerIp(sessions[id].remoteIp) != 0)
|
||||
{
|
||||
//if(ftpRemoveUPNPPortForward)
|
||||
//{
|
||||
//if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, removing UPNP port forward [%d]\n", id,sessions[id].remoteFTPServerPassivePort);
|
||||
//if(VERBOSE_MODE_ENABLED) printf("In ftpCmdPasv sessionId = %d, removing UPNP port forward [%d]\n", id,sessions[id].remoteFTPServerPassivePort);
|
||||
|
||||
//ftpRemoveUPNPPortForward(sessions[id].remoteFTPServerPassivePort, sessions[id].remoteFTPServerPassivePort);
|
||||
sessions[id].remoteFTPServerPassivePort = 0;
|
||||
//}
|
||||
}
|
||||
//if(sessions[id].open) {
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpCloseSession about to Close socket = %d, dataSocket = %d, activeDataSocket = %d, for sessionId = %d\n",sessions[id].ctrlSocket,sessions[id].passiveDataSocket,sessions[id].activeTrans.dataSocket,id);
|
||||
|
||||
//if(sessions[id].open) {
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpCloseSession about to Close socket = %d, dataSocket = %d, activeDataSocket = %d, for sessionId = %d\n",sessions[id].ctrlSocket,sessions[id].passiveDataSocket,sessions[id].activeTrans.dataSocket,id);
|
||||
|
||||
ftpUntrackSocket(sessions[id].ctrlSocket);
|
||||
ftpCloseSocket(&sessions[id].ctrlSocket);
|
||||
ftpCloseTransmission(id);
|
||||
ftpCloseSocket(&sessions[id].ctrlSocket);
|
||||
ftpCloseTransmission(id);
|
||||
ftpUntrackSocket(sessions[id].passiveDataSocket);
|
||||
ftpCloseSocket(&sessions[id].passiveDataSocket);
|
||||
//}
|
||||
sessions[id].remoteIp = 0;
|
||||
sessions[id].ctrlSocket = 0;
|
||||
sessions[id].passiveDataSocket = 0;
|
||||
sessions[id].passiveIp = 0;
|
||||
sessions[id].passivePort = 0;
|
||||
sessions[id].activeTrans.dataSocket = 0;
|
||||
sessions[id].activeTrans.op = OP_NOP;
|
||||
sessions[id].activeTrans.fileSize = 0;
|
||||
sessions[id].open = FALSE;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("Session %d closed\n", id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointer to session struct
|
||||
*
|
||||
* @param id Session id
|
||||
*
|
||||
* @return pointer to session data
|
||||
*/
|
||||
ftpSession_S* ftpGetSession(int id)
|
||||
{
|
||||
return &sessions[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Normalizes a path string
|
||||
*
|
||||
* The function resolves all dot and doubledot directory entries in the
|
||||
* passed path. If the normalized path refers beyond root, root is returned.
|
||||
*
|
||||
* @param path string of an absolute path
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
LOCAL int normalizePath(char* path)
|
||||
{
|
||||
char *in;
|
||||
char *r = NULL;
|
||||
|
||||
r = path;
|
||||
in = path;
|
||||
|
||||
while((in = strchr(in, '/')))
|
||||
{
|
||||
if(!strncmp(in, "/./", 3))
|
||||
{
|
||||
ftpStrcpy(in, &in[2]);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(in, "/."))
|
||||
{
|
||||
in[1] = '\0';
|
||||
continue;
|
||||
}
|
||||
if(!strncmp(in, "/../", 4))
|
||||
{
|
||||
*in = '\0';
|
||||
r = strrchr(path, '/');
|
||||
if(r == NULL)
|
||||
r = path;
|
||||
ftpStrcpy(r, &in[3]);
|
||||
in = r;
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(in, "/.."))
|
||||
{
|
||||
*in = '\0';
|
||||
r = strrchr(path, '/');
|
||||
if(r)
|
||||
{
|
||||
if(r == path)
|
||||
r[1] = '\0';
|
||||
else
|
||||
*r = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
in[0] = '/';
|
||||
in[1] = '\0';
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Translate a ftp session path to server path
|
||||
*
|
||||
* The translated path depends on the current working directory of the
|
||||
* session and the root path of the session. In addition the path will
|
||||
* be normalized.
|
||||
* The server path is generated as followed:
|
||||
* passed path is relative => server path = ftp user root + session working dir + path
|
||||
* passed path is absolute => server path = ftp user root + path
|
||||
*
|
||||
* @param id Session id
|
||||
* @param path ftp session path (can be relative or absolute)
|
||||
* @param if != 0 dot and doubledot directories will be resolved
|
||||
*
|
||||
* @return translated absolute server path
|
||||
*/
|
||||
const char* ftpGetRealPath(int id, const char* path, int normalize)
|
||||
{
|
||||
const char* ftpRoot;
|
||||
int len;
|
||||
|
||||
sessions[id].passiveDataSocket = 0;
|
||||
sessions[id].passiveIp = 0;
|
||||
sessions[id].passivePort = 0;
|
||||
sessions[id].activeTrans.dataSocket = 0;
|
||||
sessions[id].activeTrans.op = OP_NOP;
|
||||
sessions[id].activeTrans.fileSize = 0;
|
||||
sessions[id].open = FALSE;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("Session %d closed\n", id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns pointer to session struct
|
||||
*
|
||||
* @param id Session id
|
||||
*
|
||||
* @return pointer to session data
|
||||
*/
|
||||
ftpSession_S* ftpGetSession(int id)
|
||||
{
|
||||
return &sessions[id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Normalizes a path string
|
||||
*
|
||||
* The function resolves all dot and doubledot directory entries in the
|
||||
* passed path. If the normalized path refers beyond root, root is returned.
|
||||
*
|
||||
* @param path string of an absolute path
|
||||
*
|
||||
* @return 0
|
||||
*/
|
||||
LOCAL int normalizePath(char* path)
|
||||
{
|
||||
char *in;
|
||||
char *r = NULL;
|
||||
|
||||
r = path;
|
||||
in = path;
|
||||
|
||||
while((in = strchr(in, '/')))
|
||||
{
|
||||
if(!strncmp(in, "/./", 3))
|
||||
{
|
||||
ftpStrcpy(in, &in[2]);
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(in, "/."))
|
||||
{
|
||||
in[1] = '\0';
|
||||
continue;
|
||||
}
|
||||
if(!strncmp(in, "/../", 4))
|
||||
{
|
||||
*in = '\0';
|
||||
r = strrchr(path, '/');
|
||||
if(r == NULL)
|
||||
r = path;
|
||||
ftpStrcpy(r, &in[3]);
|
||||
in = r;
|
||||
continue;
|
||||
}
|
||||
if(!strcmp(in, "/.."))
|
||||
{
|
||||
*in = '\0';
|
||||
r = strrchr(path, '/');
|
||||
if(r)
|
||||
{
|
||||
if(r == path)
|
||||
r[1] = '\0';
|
||||
else
|
||||
*r = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
in[0] = '/';
|
||||
in[1] = '\0';
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
in++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Translate a ftp session path to server path
|
||||
*
|
||||
* The translated path depends on the current working directory of the
|
||||
* session and the root path of the session. In addition the path will
|
||||
* be normalized.
|
||||
* The server path is generated as followed:
|
||||
* passed path is relative => server path = ftp user root + session working dir + path
|
||||
* passed path is absolute => server path = ftp user root + path
|
||||
*
|
||||
* @param id Session id
|
||||
* @param path ftp session path (can be relative or absolute)
|
||||
* @param if != 0 dot and doubledot directories will be resolved
|
||||
*
|
||||
* @return translated absolute server path
|
||||
*/
|
||||
const char* ftpGetRealPath(int id, const char* path, int normalize)
|
||||
{
|
||||
const char* ftpRoot;
|
||||
int len;
|
||||
|
||||
ftpRoot = ftpGetRoot(sessions[id].userId, &len);
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("#1 ftpGetRealPath id = %d path [%s] ftpRoot [%s] sessions[id].workingDir [%s] normalize = %d\n", id, path, ftpRoot, sessions[id].workingDir,normalize);
|
||||
if(VERBOSE_MODE_ENABLED) printf("#1 ftpGetRealPath id = %d path [%s] ftpRoot [%s] sessions[id].workingDir [%s] normalize = %d\n", id, path, ftpRoot, sessions[id].workingDir,normalize);
|
||||
|
||||
pathScratchBuf[0]='\0';
|
||||
if(path[0] == '/' || strcmp(path,sessions[id].workingDir) == 0) // absolute path?
|
||||
pathScratchBuf[0]='\0';
|
||||
if(path[0] == '/' || strcmp(path,sessions[id].workingDir) == 0) // absolute path?
|
||||
{
|
||||
ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL);
|
||||
}
|
||||
else
|
||||
ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpMergePaths(pathScratchBuf, ftpRoot, sessions[id].workingDir, "/", path, NULL);
|
||||
//ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL);
|
||||
}
|
||||
//ftpMergePaths(pathScratchBuf, ftpRoot, path, NULL);
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf);
|
||||
|
||||
ftpRemoveDoubleSlash(pathScratchBuf);
|
||||
if(normalize) {
|
||||
if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf);
|
||||
|
||||
ftpRemoveDoubleSlash(pathScratchBuf);
|
||||
if(normalize) {
|
||||
normalizePath(pathScratchBuf);
|
||||
}
|
||||
ftpRemoveTrailingSlash(pathScratchBuf);
|
||||
}
|
||||
ftpRemoveTrailingSlash(pathScratchBuf);
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf);
|
||||
|
||||
return pathScratchBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change the current working directory of the session
|
||||
*
|
||||
* @param id Session id
|
||||
* @param path destination ftp path (can be relative or absolute)
|
||||
*
|
||||
* @return 0 on success; -2 if the directory doesn't exist
|
||||
*/
|
||||
int ftpChangeDir(int id, const char* path)
|
||||
{
|
||||
ftpPathInfo_S fileInfo;
|
||||
const char* realPath = ftpGetRealPath(id, path, TRUE);
|
||||
int len;
|
||||
|
||||
|
||||
ftpGetRoot(sessions[id].userId, &len); // determine len of root-path
|
||||
if(len == 1) // if len == 1 root-path == '/'
|
||||
len = 0;
|
||||
if(VERBOSE_MODE_ENABLED) printf("#2 ftpGetRealPath path [%s] ftpRoot [%s] pathScratchBuf [%s]\n", path, ftpRoot, pathScratchBuf);
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir);
|
||||
|
||||
if(ftpStat(realPath, &fileInfo) || (fileInfo.type != TYPE_DIR)) // directory accessible?
|
||||
return -2;
|
||||
|
||||
strncpy(sessions[id].workingDir, &realPath[len], MAX_PATH_LEN); // apply path
|
||||
if(sessions[id].workingDir[0] == '\0')
|
||||
strcpy(sessions[id].workingDir, "/");
|
||||
return pathScratchBuf;
|
||||
}
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] NEW sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo documentation
|
||||
*/
|
||||
void ftpOpenTransmission(int id, operation_E op, void* fsHandle, socket_t dataSocket, uint32_t fileSize)
|
||||
{
|
||||
actTransCnt++;
|
||||
sessions[id].activeTrans.op = op;
|
||||
sessions[id].activeTrans.fsHandle = fsHandle;
|
||||
sessions[id].activeTrans.dataSocket = dataSocket;
|
||||
sessions[id].activeTrans.fileSize = fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo documentation
|
||||
*/
|
||||
void ftpCloseTransmission(int id)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpCloseTransmission about to Close socket = %d, for sessionId = %d, fsHandle [%p] op = %d\n",
|
||||
sessions[id].activeTrans.dataSocket, id,sessions[id].activeTrans.fsHandle,sessions[id].activeTrans.op);
|
||||
|
||||
if(sessions[id].activeTrans.dataSocket > 0)
|
||||
{
|
||||
ftpUntrackSocket(sessions[id].activeTrans.dataSocket);
|
||||
ftpCloseSocket(&sessions[id].activeTrans.dataSocket);
|
||||
}
|
||||
|
||||
if(sessions[id].activeTrans.op != OP_NOP) // is thera an active transmission?
|
||||
{
|
||||
if(sessions[id].activeTrans.op == OP_LIST)
|
||||
{
|
||||
ftpCloseDir(sessions[id].activeTrans.fsHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpCloseFile(sessions[id].activeTrans.fsHandle);
|
||||
}
|
||||
sessions[id].activeTrans.fsHandle = NULL;
|
||||
sessions[id].activeTrans.op = OP_NOP;
|
||||
sessions[id].activeTrans.dataSocket = 0;
|
||||
actTransCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo documentation
|
||||
*/
|
||||
int ftpGetActiveTransCnt(void)
|
||||
{
|
||||
return actTransCnt;
|
||||
}
|
||||
/**
|
||||
* @brief Change the current working directory of the session
|
||||
*
|
||||
* @param id Session id
|
||||
* @param path destination ftp path (can be relative or absolute)
|
||||
*
|
||||
* @return 0 on success; -2 if the directory doesn't exist
|
||||
*/
|
||||
int ftpChangeDir(int id, const char* path)
|
||||
{
|
||||
ftpPathInfo_S fileInfo;
|
||||
const char* realPath = ftpGetRealPath(id, path, TRUE);
|
||||
int len;
|
||||
|
||||
|
||||
ftpGetRoot(sessions[id].userId, &len); // determine len of root-path
|
||||
if(len == 1) // if len == 1 root-path == '/'
|
||||
len = 0;
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir);
|
||||
|
||||
if(ftpStat(realPath, &fileInfo) || (fileInfo.type != TYPE_DIR)) // directory accessible?
|
||||
return -2;
|
||||
|
||||
strncpy(sessions[id].workingDir, &realPath[len], MAX_PATH_LEN); // apply path
|
||||
if(sessions[id].workingDir[0] == '\0')
|
||||
strcpy(sessions[id].workingDir, "/");
|
||||
|
||||
if(VERBOSE_MODE_ENABLED) printf("ftpChangeDir path [%s] realPath [%s] NEW sessions[id].workingDir [%s]\n", path, realPath, sessions[id].workingDir);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo documentation
|
||||
*/
|
||||
void ftpOpenTransmission(int id, operation_E op, void* fsHandle, socket_t dataSocket, uint32_t fileSize)
|
||||
{
|
||||
actTransCnt++;
|
||||
sessions[id].activeTrans.op = op;
|
||||
sessions[id].activeTrans.fsHandle = fsHandle;
|
||||
sessions[id].activeTrans.dataSocket = dataSocket;
|
||||
sessions[id].activeTrans.fileSize = fileSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo documentation
|
||||
*/
|
||||
void ftpCloseTransmission(int id)
|
||||
{
|
||||
if(VERBOSE_MODE_ENABLED) printf("In ftpCloseTransmission about to Close socket = %d, for sessionId = %d, fsHandle [%p] op = %d\n",
|
||||
sessions[id].activeTrans.dataSocket, id,sessions[id].activeTrans.fsHandle,sessions[id].activeTrans.op);
|
||||
|
||||
if(sessions[id].activeTrans.dataSocket > 0)
|
||||
{
|
||||
ftpUntrackSocket(sessions[id].activeTrans.dataSocket);
|
||||
ftpCloseSocket(&sessions[id].activeTrans.dataSocket);
|
||||
}
|
||||
|
||||
if(sessions[id].activeTrans.op != OP_NOP) // is thera an active transmission?
|
||||
{
|
||||
if(sessions[id].activeTrans.op == OP_LIST)
|
||||
{
|
||||
ftpCloseDir(sessions[id].activeTrans.fsHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
ftpCloseFile(sessions[id].activeTrans.fsHandle);
|
||||
}
|
||||
sessions[id].activeTrans.fsHandle = NULL;
|
||||
sessions[id].activeTrans.op = OP_NOP;
|
||||
sessions[id].activeTrans.dataSocket = 0;
|
||||
actTransCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo documentation
|
||||
*/
|
||||
int ftpGetActiveTransCnt(void)
|
||||
{
|
||||
return actTransCnt;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,246 +1,246 @@
|
||||
// ==============================================================
|
||||
// This file is part of Glest Shared Library (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<74>o Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
#include "shader_gl.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "opengl.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Shared{ namespace Graphics{ namespace Gl{
|
||||
|
||||
// =====================================================
|
||||
// class ShaderProgramGl
|
||||
// =====================================================
|
||||
|
||||
ShaderProgramGl::ShaderProgramGl(){
|
||||
inited= false;
|
||||
}
|
||||
|
||||
void ShaderProgramGl::init(){
|
||||
if(!inited){
|
||||
assertGl();
|
||||
handle= glCreateProgramObjectARB();
|
||||
assertGl();
|
||||
inited= true;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgramGl::end(){
|
||||
if(inited){
|
||||
assertGl();
|
||||
glDeleteObjectARB(handle);
|
||||
assertGl();
|
||||
inited= false;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgramGl::attach(VertexShader *vertexShader, FragmentShader *fragmentShader){
|
||||
this->vertexShader= vertexShader;
|
||||
this->fragmentShader= fragmentShader;
|
||||
}
|
||||
|
||||
bool ShaderProgramGl::link(string &messages){
|
||||
assertGl();
|
||||
|
||||
VertexShaderGl *vertexShaderGl= static_cast<VertexShaderGl*>(vertexShader);
|
||||
FragmentShaderGl *fragmentShaderGl= static_cast<FragmentShaderGl*>(fragmentShader);
|
||||
|
||||
const ShaderSource *vss= vertexShaderGl->getSource();
|
||||
const ShaderSource *fss= fragmentShaderGl->getSource();
|
||||
messages= "Linking program: " + vss->getPathInfo() + ", " + fss->getPathInfo() + "\n";
|
||||
|
||||
//attach
|
||||
glAttachObjectARB(handle, vertexShaderGl->getHandle());
|
||||
glAttachObjectARB(handle, fragmentShaderGl->getHandle());
|
||||
|
||||
assertGl();
|
||||
|
||||
//bind attributes
|
||||
for(unsigned int i=0; i<attributes.size(); ++i){
|
||||
int a= attributes[i].second;
|
||||
string s= attributes[i].first;
|
||||
glBindAttribLocationARB(handle, attributes[i].second, attributes[i].first.c_str());
|
||||
}
|
||||
|
||||
assertGl();
|
||||
|
||||
//link
|
||||
glLinkProgramARB(handle);
|
||||
glValidateProgramARB(handle);
|
||||
|
||||
assertGl();
|
||||
|
||||
//log
|
||||
GLint logLength= 0;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
|
||||
char *buffer= new char[logLength+1];
|
||||
glGetInfoLogARB(handle, logLength+1, NULL, buffer);
|
||||
messages+= buffer;
|
||||
delete [] buffer;
|
||||
|
||||
assertGl();
|
||||
|
||||
//status
|
||||
GLint status= false;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_LINK_STATUS_ARB, &status);
|
||||
|
||||
assertGl();
|
||||
|
||||
return status!=0;
|
||||
}
|
||||
|
||||
void ShaderProgramGl::activate(){
|
||||
assertGl();
|
||||
glUseProgramObjectARB(handle);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::deactivate(){
|
||||
assertGl();
|
||||
glUseProgramObjectARB(0);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, int value){
|
||||
assertGl();
|
||||
glUniform1iARB(getLocation(name), value);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, float value){
|
||||
assertGl();
|
||||
glUniform1fARB(getLocation(name), value);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Vec2f &value){
|
||||
assertGl();
|
||||
glUniform2fvARB(getLocation(name), 1, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Vec3f &value){
|
||||
assertGl();
|
||||
glUniform3fvARB(getLocation(name), 1, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Vec4f &value){
|
||||
assertGl();
|
||||
glUniform4fvARB(getLocation(name), 1, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Matrix3f &value){
|
||||
assertGl();
|
||||
glUniformMatrix3fvARB(getLocation(name), 1, GL_FALSE, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Matrix4f &value){
|
||||
assertGl();
|
||||
glUniformMatrix4fvARB(getLocation(name), 1, GL_FALSE, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::bindAttribute(const string &name, int index){
|
||||
attributes.push_back(AttributePair(name, index));
|
||||
}
|
||||
|
||||
GLint ShaderProgramGl::getLocation(const string &name){
|
||||
GLint location= glGetUniformLocationARB(handle, name.c_str());
|
||||
if(location==-1){
|
||||
throw runtime_error("Can't locate uniform: "+ name);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// class ShaderGl
|
||||
// ===============================================
|
||||
|
||||
ShaderGl::ShaderGl(){
|
||||
inited= false;
|
||||
}
|
||||
|
||||
void ShaderGl::load(const string &path){
|
||||
source.load(path);
|
||||
}
|
||||
|
||||
bool ShaderGl::compile(string &messages){
|
||||
|
||||
assertGl();
|
||||
|
||||
messages= "Compiling shader: " + source.getPathInfo() + "\n";
|
||||
|
||||
//load source
|
||||
GLint length= (GLint)source.getCode().size();
|
||||
const GLcharARB *csource= source.getCode().c_str();
|
||||
glShaderSourceARB(handle, 1, &csource, &length);
|
||||
|
||||
//compile
|
||||
glCompileShaderARB(handle);
|
||||
|
||||
//log
|
||||
GLint logLength= 0;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
|
||||
char *buffer= new char[logLength+1];
|
||||
glGetInfoLogARB(handle, logLength+1, NULL, buffer);
|
||||
messages+= buffer;
|
||||
delete [] buffer;
|
||||
|
||||
//status
|
||||
GLint status= false;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &status);
|
||||
assertGl();
|
||||
|
||||
return status!=0;
|
||||
}
|
||||
|
||||
void ShaderGl::end(){
|
||||
if(inited){
|
||||
assertGl();
|
||||
glDeleteObjectARB(handle);
|
||||
assertGl();
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// class VertexShaderGl
|
||||
// ===============================================
|
||||
|
||||
void VertexShaderGl::init(){
|
||||
if(!inited){
|
||||
assertGl();
|
||||
handle= glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
assertGl();
|
||||
inited= true;
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// class FragmentShaderGl
|
||||
// ===============================================
|
||||
|
||||
void FragmentShaderGl::init(){
|
||||
if(!inited){
|
||||
assertGl();
|
||||
handle= glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
assertGl();
|
||||
inited= true;
|
||||
}
|
||||
}
|
||||
|
||||
}}}//end namespace
|
||||
// ==============================================================
|
||||
// This file is part of Glest Shared Library (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Marti<74>o Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
#include "shader_gl.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "opengl.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Shared{ namespace Graphics{ namespace Gl{
|
||||
|
||||
// =====================================================
|
||||
// class ShaderProgramGl
|
||||
// =====================================================
|
||||
|
||||
ShaderProgramGl::ShaderProgramGl(){
|
||||
inited= false;
|
||||
}
|
||||
|
||||
void ShaderProgramGl::init(){
|
||||
if(!inited){
|
||||
assertGl();
|
||||
handle= glCreateProgramObjectARB();
|
||||
assertGl();
|
||||
inited= true;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgramGl::end(){
|
||||
if(inited){
|
||||
assertGl();
|
||||
glDeleteObjectARB(handle);
|
||||
assertGl();
|
||||
inited= false;
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderProgramGl::attach(VertexShader *vertexShader, FragmentShader *fragmentShader){
|
||||
this->vertexShader= vertexShader;
|
||||
this->fragmentShader= fragmentShader;
|
||||
}
|
||||
|
||||
bool ShaderProgramGl::link(string &messages){
|
||||
assertGl();
|
||||
|
||||
VertexShaderGl *vertexShaderGl= static_cast<VertexShaderGl*>(vertexShader);
|
||||
FragmentShaderGl *fragmentShaderGl= static_cast<FragmentShaderGl*>(fragmentShader);
|
||||
|
||||
const ShaderSource *vss= vertexShaderGl->getSource();
|
||||
const ShaderSource *fss= fragmentShaderGl->getSource();
|
||||
messages= "Linking program: " + vss->getPathInfo() + ", " + fss->getPathInfo() + "\n";
|
||||
|
||||
//attach
|
||||
glAttachObjectARB(handle, vertexShaderGl->getHandle());
|
||||
glAttachObjectARB(handle, fragmentShaderGl->getHandle());
|
||||
|
||||
assertGl();
|
||||
|
||||
//bind attributes
|
||||
for(unsigned int i=0; i<attributes.size(); ++i){
|
||||
int a= attributes[i].second;
|
||||
string s= attributes[i].first;
|
||||
glBindAttribLocationARB(handle, attributes[i].second, attributes[i].first.c_str());
|
||||
}
|
||||
|
||||
assertGl();
|
||||
|
||||
//link
|
||||
glLinkProgramARB(handle);
|
||||
glValidateProgramARB(handle);
|
||||
|
||||
assertGl();
|
||||
|
||||
//log
|
||||
GLint logLength= 0;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
|
||||
char *buffer= new char[logLength+1];
|
||||
glGetInfoLogARB(handle, logLength+1, NULL, buffer);
|
||||
messages+= buffer;
|
||||
delete [] buffer;
|
||||
|
||||
assertGl();
|
||||
|
||||
//status
|
||||
GLint status= false;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_LINK_STATUS_ARB, &status);
|
||||
|
||||
assertGl();
|
||||
|
||||
return status!=0;
|
||||
}
|
||||
|
||||
void ShaderProgramGl::activate(){
|
||||
assertGl();
|
||||
glUseProgramObjectARB(handle);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::deactivate(){
|
||||
assertGl();
|
||||
glUseProgramObjectARB(0);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, int value){
|
||||
assertGl();
|
||||
glUniform1iARB(getLocation(name), value);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, float value){
|
||||
assertGl();
|
||||
glUniform1fARB(getLocation(name), value);
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Vec2f &value){
|
||||
assertGl();
|
||||
glUniform2fvARB(getLocation(name), 1, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Vec3f &value){
|
||||
assertGl();
|
||||
glUniform3fvARB(getLocation(name), 1, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Vec4f &value){
|
||||
assertGl();
|
||||
glUniform4fvARB(getLocation(name), 1, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Matrix3f &value){
|
||||
assertGl();
|
||||
glUniformMatrix3fvARB(getLocation(name), 1, GL_FALSE, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::setUniform(const string &name, const Matrix4f &value){
|
||||
assertGl();
|
||||
glUniformMatrix4fvARB(getLocation(name), 1, GL_FALSE, value.ptr());
|
||||
assertGl();
|
||||
}
|
||||
|
||||
void ShaderProgramGl::bindAttribute(const string &name, int index){
|
||||
attributes.push_back(AttributePair(name, index));
|
||||
}
|
||||
|
||||
GLint ShaderProgramGl::getLocation(const string &name){
|
||||
GLint location= glGetUniformLocationARB(handle, name.c_str());
|
||||
if(location==-1){
|
||||
throw runtime_error("Can't locate uniform: "+ name);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// class ShaderGl
|
||||
// ===============================================
|
||||
|
||||
ShaderGl::ShaderGl(){
|
||||
inited= false;
|
||||
}
|
||||
|
||||
void ShaderGl::load(const string &path){
|
||||
source.load(path);
|
||||
}
|
||||
|
||||
bool ShaderGl::compile(string &messages){
|
||||
|
||||
assertGl();
|
||||
|
||||
messages= "Compiling shader: " + source.getPathInfo() + "\n";
|
||||
|
||||
//load source
|
||||
GLint length= (GLint)source.getCode().size();
|
||||
const GLcharARB *csource= source.getCode().c_str();
|
||||
glShaderSourceARB(handle, 1, &csource, &length);
|
||||
|
||||
//compile
|
||||
glCompileShaderARB(handle);
|
||||
|
||||
//log
|
||||
GLint logLength= 0;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);
|
||||
char *buffer= new char[logLength+1];
|
||||
glGetInfoLogARB(handle, logLength+1, NULL, buffer);
|
||||
messages+= buffer;
|
||||
delete [] buffer;
|
||||
|
||||
//status
|
||||
GLint status= false;
|
||||
glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &status);
|
||||
assertGl();
|
||||
|
||||
return status!=0;
|
||||
}
|
||||
|
||||
void ShaderGl::end(){
|
||||
if(inited){
|
||||
assertGl();
|
||||
glDeleteObjectARB(handle);
|
||||
assertGl();
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// class VertexShaderGl
|
||||
// ===============================================
|
||||
|
||||
void VertexShaderGl::init(){
|
||||
if(!inited){
|
||||
assertGl();
|
||||
handle= glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
assertGl();
|
||||
inited= true;
|
||||
}
|
||||
}
|
||||
|
||||
// ===============================================
|
||||
// class FragmentShaderGl
|
||||
// ===============================================
|
||||
|
||||
void FragmentShaderGl::init(){
|
||||
if(!inited){
|
||||
assertGl();
|
||||
handle= glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
assertGl();
|
||||
inited= true;
|
||||
}
|
||||
}
|
||||
|
||||
}}}//end namespace
|
||||
|
@@ -12,7 +12,7 @@
|
||||
#include "texture_manager.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <stdexcept>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "graphics_interface.h"
|
||||
#include "graphics_factory.h"
|
||||
|
@@ -514,7 +514,7 @@ void FTPClientThread::execute() {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"FTP Client thread is running\n");
|
||||
|
||||
try {
|
||||
while(this->getQuitStatus() == false) {
|
||||
while(this->getQuitStatus() == false) {
|
||||
MutexSafeWrapper safeMutex(&mutexMapFileList);
|
||||
if(mapFileList.size() > 0) {
|
||||
string mapFilename = mapFileList[0];
|
||||
@@ -546,7 +546,7 @@ void FTPClientThread::execute() {
|
||||
if(this->getQuitStatus() == false) {
|
||||
sleep(25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Client exiting!\n");
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Client exiting!\n");
|
||||
|
@@ -126,21 +126,21 @@ void FTPServerThread::execute() {
|
||||
}
|
||||
|
||||
/*
|
||||
ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
ftpCreateAccount("nothing", "", "./", 0);
|
||||
ftpCreateAccount("reader", "", "./", FTP_ACC_RD);
|
||||
ftpCreateAccount("writer", "", "./", FTP_ACC_WR);
|
||||
ftpCreateAccount("lister", "", "./", FTP_ACC_LS);
|
||||
ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
*/
|
||||
ftpStart(portNumber);
|
||||
while(this->getQuitStatus() == false) {
|
||||
ftpCreateAccount("anonymous", "", "./", FTP_ACC_RD | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
ftpCreateAccount("nothing", "", "./", 0);
|
||||
ftpCreateAccount("reader", "", "./", FTP_ACC_RD);
|
||||
ftpCreateAccount("writer", "", "./", FTP_ACC_WR);
|
||||
ftpCreateAccount("lister", "", "./", FTP_ACC_LS);
|
||||
ftpCreateAccount("admin", "xxx", "./", FTP_ACC_RD | FTP_ACC_WR | FTP_ACC_LS | FTP_ACC_DIR);
|
||||
*/
|
||||
ftpStart(portNumber);
|
||||
while(this->getQuitStatus() == false) {
|
||||
ftpExecute();
|
||||
//if(processedWork == 0) {
|
||||
//sleep(25);
|
||||
//}
|
||||
}
|
||||
ftpShutdown();
|
||||
}
|
||||
ftpShutdown();
|
||||
|
||||
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("===> FTP Server exiting!\n");
|
||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"===> FTP Server exiting!\n");
|
||||
|
@@ -1972,7 +1972,7 @@ void UPNP_Tools::AddUPNPPortForward(int internalPort, int externalPort) {
|
||||
|
||||
void UPNP_Tools::RemoveUPNPPortForward(int internalPort, int externalPort) {
|
||||
UPNP_Tools::upnp_rem_redirect(externalPort);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// This code below handles Universal Plug and Play Router Discovery
|
||||
|
@@ -73,13 +73,13 @@ Window::Window() {
|
||||
mouseState.clear();
|
||||
|
||||
#ifdef WIN32
|
||||
init_win32();
|
||||
init_win32();
|
||||
#endif
|
||||
}
|
||||
|
||||
Window::~Window() {
|
||||
#ifdef WIN32
|
||||
done_win32();
|
||||
done_win32();
|
||||
#endif
|
||||
|
||||
assert(global_window == this);
|
||||
@@ -201,72 +201,72 @@ bool Window::handleEvent() {
|
||||
break;
|
||||
case SDL_ACTIVEEVENT:
|
||||
{
|
||||
codeLocation = "k";
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SDL_ACTIVEEVENT event.active.state = %d event.active. = %d\n",__FILE__,__FUNCTION__,__LINE__,event.active.state,event.active.gain);
|
||||
|
||||
codeLocation = "k";
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SDL_ACTIVEEVENT event.active.state = %d event.active. = %d\n",__FILE__,__FUNCTION__,__LINE__,event.active.state,event.active.gain);
|
||||
|
||||
// Check if the program has lost keyboard focus
|
||||
/*
|
||||
if (event.active.state == SDL_APPINPUTFOCUS) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
/*
|
||||
if (event.active.state == SDL_APPINPUTFOCUS) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
//else if (event.active.gain == 1) {
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::isActive);
|
||||
|
||||
bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly());
|
||||
showCursor(willShowCursor);
|
||||
}
|
||||
*/
|
||||
// Check if the program has lost window focus
|
||||
if ((event.active.state & SDL_APPACTIVE) == SDL_APPACTIVE) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
//else if (event.active.gain == 1) {
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::isActive);
|
||||
|
||||
bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly());
|
||||
showCursor(willShowCursor);
|
||||
}
|
||||
*/
|
||||
// Check if the program has lost window focus
|
||||
/*
|
||||
if (event.active.state == SDL_APPMOUSEFOCUS) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
if ((event.active.state & SDL_APPACTIVE) == SDL_APPACTIVE) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
//else if (event.active.gain == 1) {
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::isActive);
|
||||
|
||||
bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly());
|
||||
showCursor(willShowCursor);
|
||||
}
|
||||
// Check if the program has lost window focus
|
||||
/*
|
||||
if (event.active.state == SDL_APPMOUSEFOCUS) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
//else if (event.active.gain == 1) {
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::isActive);
|
||||
bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly());
|
||||
showCursor(willShowCursor);
|
||||
}
|
||||
*/
|
||||
*/
|
||||
if ((event.active.state & SDL_APPMOUSEFOCUS) != SDL_APPMOUSEFOCUS &&
|
||||
(event.active.state & SDL_APPINPUTFOCUS) != SDL_APPINPUTFOCUS &&
|
||||
(event.active.state & SDL_APPACTIVE) != SDL_APPACTIVE) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
(event.active.state & SDL_APPACTIVE) != SDL_APPACTIVE) {
|
||||
if (event.active.gain == 0) {
|
||||
Window::isActive = false;
|
||||
}
|
||||
//else if (event.active.gain == 1) {
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
else {
|
||||
Window::isActive = true;
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Window::isActive = %d, event.active.state = %d\n",__FILE__,__FUNCTION__,__LINE__,Window::isActive,event.active.state);
|
||||
bool willShowCursor = (!Window::isActive || (Window::lastShowMouseState == SDL_ENABLE) || Window::getUseDefaultCursorOnly());
|
||||
showCursor(willShowCursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -385,15 +385,15 @@ void Window::setupGraphicsScreen(int depthBits, int stencilBits, bool hardware_a
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
static HWND GetSDLWindow()
|
||||
{
|
||||
SDL_SysWMinfo info;
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWMInfo(&info) == -1)
|
||||
return NULL;
|
||||
return info.window;
|
||||
}
|
||||
static HWND GetSDLWindow()
|
||||
{
|
||||
SDL_SysWMinfo info;
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
if (SDL_GetWMInfo(&info) == -1)
|
||||
return NULL;
|
||||
return info.window;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -402,84 +402,84 @@ void Window::toggleFullscreen() {
|
||||
|
||||
Window::isFullScreen = !Window::isFullScreen;
|
||||
#ifdef WIN32
|
||||
/* -- Portable Fullscreen Toggling --
|
||||
As of SDL 1.2.10, if width and height are both 0, SDL_SetVideoMode will use the
|
||||
width and height of the current video mode (or the desktop mode, if no mode has been set).
|
||||
Use 0 for Height, Width, and Color Depth to keep the current values. */
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(Window::allowAltEnterFullscreenToggle == true) {
|
||||
SDL_Surface *cur_surface = SDL_GetVideoSurface();
|
||||
if(cur_surface != NULL) {
|
||||
Window::isFullScreen = !((cur_surface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN);
|
||||
}
|
||||
|
||||
SDL_Surface *sf = SDL_GetVideoSurface();
|
||||
SDL_Surface **surface = &sf;
|
||||
uint32 *flags = NULL;
|
||||
void *pixels = NULL;
|
||||
SDL_Color *palette = NULL;
|
||||
SDL_Rect clip;
|
||||
int ncolors = 0;
|
||||
Uint32 tmpflags = 0;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
int bpp = 0;
|
||||
|
||||
if ( (!surface) || (!(*surface)) ) // don't bother if there's no surface.
|
||||
return;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
tmpflags = (*surface)->flags;
|
||||
w = (*surface)->w;
|
||||
h = (*surface)->h;
|
||||
bpp = (*surface)->format->BitsPerPixel;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n w = %d, h = %d, bpp = %d",__FILE__,__FUNCTION__,__LINE__,w,h,bpp);
|
||||
|
||||
if (flags == NULL) // use the surface's flags.
|
||||
flags = &tmpflags;
|
||||
|
||||
//
|
||||
if ( *flags & SDL_FULLSCREEN )
|
||||
*flags &= ~SDL_FULLSCREEN;
|
||||
//
|
||||
else
|
||||
*flags |= SDL_FULLSCREEN;
|
||||
|
||||
SDL_GetClipRect(*surface, &clip);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
*surface = SDL_SetVideoMode(w, h, bpp, (*flags));
|
||||
|
||||
if (*surface == NULL) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
*surface = SDL_SetVideoMode(w, h, bpp, tmpflags);
|
||||
} // if
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
SDL_SetClipRect(*surface, &clip);
|
||||
}
|
||||
else {
|
||||
HWND handle = GetSDLWindow();
|
||||
if(Window::isFullScreen == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] Window::isFullScreen == true [%d]\n",__FILE__,__FUNCTION__,__LINE__,handle);
|
||||
/* -- Portable Fullscreen Toggling --
|
||||
As of SDL 1.2.10, if width and height are both 0, SDL_SetVideoMode will use the
|
||||
width and height of the current video mode (or the desktop mode, if no mode has been set).
|
||||
Use 0 for Height, Width, and Color Depth to keep the current values. */
|
||||
|
||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(Window::allowAltEnterFullscreenToggle == true) {
|
||||
SDL_Surface *cur_surface = SDL_GetVideoSurface();
|
||||
if(cur_surface != NULL) {
|
||||
Window::isFullScreen = !((cur_surface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN);
|
||||
}
|
||||
|
||||
SDL_Surface *sf = SDL_GetVideoSurface();
|
||||
SDL_Surface **surface = &sf;
|
||||
uint32 *flags = NULL;
|
||||
void *pixels = NULL;
|
||||
SDL_Color *palette = NULL;
|
||||
SDL_Rect clip;
|
||||
int ncolors = 0;
|
||||
Uint32 tmpflags = 0;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
int bpp = 0;
|
||||
|
||||
if ( (!surface) || (!(*surface)) ) // don't bother if there's no surface.
|
||||
return;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
tmpflags = (*surface)->flags;
|
||||
w = (*surface)->w;
|
||||
h = (*surface)->h;
|
||||
bpp = (*surface)->format->BitsPerPixel;
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n w = %d, h = %d, bpp = %d",__FILE__,__FUNCTION__,__LINE__,w,h,bpp);
|
||||
|
||||
if (flags == NULL) // use the surface's flags.
|
||||
flags = &tmpflags;
|
||||
|
||||
//
|
||||
if ( *flags & SDL_FULLSCREEN )
|
||||
*flags &= ~SDL_FULLSCREEN;
|
||||
//
|
||||
else
|
||||
*flags |= SDL_FULLSCREEN;
|
||||
|
||||
SDL_GetClipRect(*surface, &clip);
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
*surface = SDL_SetVideoMode(w, h, bpp, (*flags));
|
||||
|
||||
if (*surface == NULL) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
*surface = SDL_SetVideoMode(w, h, bpp, tmpflags);
|
||||
} // if
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
SDL_SetClipRect(*surface, &clip);
|
||||
}
|
||||
else {
|
||||
HWND handle = GetSDLWindow();
|
||||
if(Window::isFullScreen == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] Window::isFullScreen == true [%d]\n",__FILE__,__FUNCTION__,__LINE__,handle);
|
||||
ShowWindow(handle, SW_MAXIMIZE);
|
||||
//if(Window::getUseDefaultCursorOnly() == false) {
|
||||
// showCursor(false);
|
||||
//}
|
||||
}
|
||||
else {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] Window::isFullScreen == false [%d]\n",__FILE__,__FUNCTION__,__LINE__,handle);
|
||||
ShowWindow(handle, SW_RESTORE);
|
||||
//showCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
//}
|
||||
}
|
||||
else {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d] Window::isFullScreen == false [%d]\n",__FILE__,__FUNCTION__,__LINE__,handle);
|
||||
ShowWindow(handle, SW_RESTORE);
|
||||
//showCursor(true);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
if(Window::allowAltEnterFullscreenToggle == true) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
@@ -1,456 +1,456 @@
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* File: glob.c
|
||||
*
|
||||
* Purpose: Definition of the glob() API functions for the Win32 platform.
|
||||
*
|
||||
* Created: 13th November 2002
|
||||
* Updated: 6th February 2010
|
||||
*
|
||||
* Home: http://synesis.com.au/software/
|
||||
*
|
||||
* Copyright (c) 2002-2010, Matthew Wilson and Synesis Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the names of Matthew Wilson and Synesis Software nor the names of
|
||||
* any contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* Includes
|
||||
*/
|
||||
|
||||
#include <glob.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
||||
#define NUM_ELEMENTS(ar) (sizeof(ar) / sizeof(ar[0]))
|
||||
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
static char const *strrpbrk(char const *string, char const *strCharSet)
|
||||
{
|
||||
char *part = NULL;
|
||||
char const *pch;
|
||||
|
||||
for(pch = strCharSet; *pch; ++pch)
|
||||
{
|
||||
char *p = strrchr(string, *pch);
|
||||
|
||||
if(NULL != p)
|
||||
{
|
||||
if(NULL == part)
|
||||
{
|
||||
part = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(part < p)
|
||||
{
|
||||
part = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* API functions
|
||||
*/
|
||||
|
||||
/* It gives you back the matched contents of your pattern, so for Win32, the
|
||||
* directories must be included
|
||||
*/
|
||||
|
||||
int glob( char const *pattern
|
||||
, int flags
|
||||
#if defined(__COMO__)
|
||||
, int (*errfunc)(char const *, int)
|
||||
#else /* ? compiler */
|
||||
, const int (*errfunc)(char const *, int)
|
||||
#endif /* compiler */
|
||||
, glob_t *pglob)
|
||||
{
|
||||
int result;
|
||||
char szRelative[1 + _MAX_PATH];
|
||||
char const *file_part;
|
||||
WIN32_FIND_DATAA find_data;
|
||||
HANDLE hFind;
|
||||
char *buffer;
|
||||
char szPattern2[1 + _MAX_PATH];
|
||||
char szPattern3[1 + _MAX_PATH];
|
||||
char const *effectivePattern = pattern;
|
||||
char const *leafMost;
|
||||
const int bMagic = (NULL != strpbrk(pattern, "?*"));
|
||||
int bNoMagic = 0;
|
||||
int bMagic0;
|
||||
size_t maxMatches = ~(size_t)(0);
|
||||
|
||||
assert(NULL != pglob);
|
||||
|
||||
if(flags & GLOB_NOMAGIC)
|
||||
{
|
||||
bNoMagic = !bMagic;
|
||||
}
|
||||
|
||||
if(flags & GLOB_LIMIT)
|
||||
{
|
||||
maxMatches = (size_t)pglob->gl_matchc;
|
||||
}
|
||||
|
||||
if(flags & GLOB_TILDE)
|
||||
{
|
||||
/* Check that begins with "~/" */
|
||||
if( '~' == pattern[0] &&
|
||||
( '\0' == pattern[1] ||
|
||||
'/' == pattern[1] ||
|
||||
'\\' == pattern[1]))
|
||||
{
|
||||
DWORD dw;
|
||||
|
||||
(void)lstrcpyA(&szPattern2[0], "%HOMEDRIVE%%HOMEPATH%");
|
||||
|
||||
dw = ExpandEnvironmentStringsA(&szPattern2[0], &szPattern3[0], NUM_ELEMENTS(szPattern3) - 1);
|
||||
|
||||
if(0 != dw)
|
||||
{
|
||||
(void)lstrcpynA(&szPattern3[0] + dw - 1, &pattern[1], (int)(NUM_ELEMENTS(szPattern3) - dw));
|
||||
szPattern3[NUM_ELEMENTS(szPattern3) - 1] = '\0';
|
||||
|
||||
effectivePattern = szPattern3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file_part = strrpbrk(effectivePattern, "\\/");
|
||||
|
||||
if(NULL != file_part)
|
||||
{
|
||||
leafMost = ++file_part;
|
||||
|
||||
(void)lstrcpyA(szRelative, effectivePattern);
|
||||
szRelative[file_part - effectivePattern] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
szRelative[0] = '\0';
|
||||
leafMost = effectivePattern;
|
||||
}
|
||||
|
||||
bMagic0 = (leafMost == strpbrk(leafMost, "?*"));
|
||||
|
||||
hFind = FindFirstFileA(effectivePattern, &find_data);
|
||||
buffer = NULL;
|
||||
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
|
||||
if(0 == (flags & GLOB_DOOFFS))
|
||||
{
|
||||
pglob->gl_offs = 0;
|
||||
}
|
||||
|
||||
if(hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* If this was a pattern search, and the
|
||||
* directory exists, then we return 0
|
||||
* matches, rather than GLOB_NOMATCH
|
||||
*/
|
||||
if( bMagic &&
|
||||
NULL != file_part)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NULL != errfunc)
|
||||
{
|
||||
(void)errfunc(effectivePattern, (int)GetLastError());
|
||||
}
|
||||
|
||||
result = GLOB_NOMATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int cbCurr = 0;
|
||||
size_t cbAlloc = 0;
|
||||
size_t cMatches = 0;
|
||||
|
||||
result = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int cch;
|
||||
size_t new_cbAlloc;
|
||||
|
||||
if( bMagic0 &&
|
||||
0 == (flags & GLOB_PERIOD))
|
||||
{
|
||||
if('.' == find_data.cFileName[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
#ifdef GLOB_ONLYFILE
|
||||
if(flags & GLOB_ONLYFILE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif /* GLOB_ONLYFILE */
|
||||
|
||||
if( bMagic0 &&
|
||||
GLOB_NODOTSDIRS == (flags & GLOB_NODOTSDIRS))
|
||||
{
|
||||
/* Pattern must begin with '.' to match either dots directory */
|
||||
if( 0 == lstrcmpA(".", find_data.cFileName) ||
|
||||
0 == lstrcmpA("..", find_data.cFileName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & GLOB_MARK)
|
||||
{
|
||||
#if 0
|
||||
if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M')
|
||||
#endif /* 0 */
|
||||
(void)lstrcatA(find_data.cFileName, "/");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(flags & GLOB_ONLYDIR)
|
||||
{
|
||||
/* Skip all further actions, and get the next entry */
|
||||
#if 0
|
||||
if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M')
|
||||
#endif /* 0 */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
cch = lstrlenA(find_data.cFileName);
|
||||
if(NULL != file_part)
|
||||
{
|
||||
cch += (int)(file_part - effectivePattern);
|
||||
}
|
||||
|
||||
new_cbAlloc = (size_t)cbCurr + cch + 1;
|
||||
if(new_cbAlloc > cbAlloc)
|
||||
{
|
||||
char *new_buffer;
|
||||
|
||||
new_cbAlloc *= 2;
|
||||
|
||||
new_cbAlloc = (new_cbAlloc + 31) & ~(31);
|
||||
|
||||
new_buffer = (char*)realloc(buffer, new_cbAlloc);
|
||||
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = new_buffer;
|
||||
cbAlloc = new_cbAlloc;
|
||||
}
|
||||
|
||||
(void)lstrcpynA(buffer + cbCurr, szRelative, 1 + (int)(file_part - effectivePattern));
|
||||
(void)lstrcatA(buffer + cbCurr, find_data.cFileName);
|
||||
cbCurr += cch + 1;
|
||||
|
||||
++cMatches;
|
||||
}
|
||||
while(FindNextFile(hFind, &find_data) && cMatches != maxMatches);
|
||||
|
||||
(void)FindClose(hFind);
|
||||
|
||||
if(result == 0)
|
||||
{
|
||||
/* Now expand the buffer, to fit in all the pointers. */
|
||||
size_t cbPointers = (1 + cMatches + pglob->gl_offs) * sizeof(char*);
|
||||
char *new_buffer = (char*)realloc(buffer, cbAlloc + cbPointers);
|
||||
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
char **pp;
|
||||
char **begin;
|
||||
char **end;
|
||||
char *next_str;
|
||||
|
||||
buffer = new_buffer;
|
||||
|
||||
(void)memmove(new_buffer + cbPointers, new_buffer, cbAlloc);
|
||||
|
||||
/* Handle the offsets. */
|
||||
begin = (char**)new_buffer;
|
||||
end = begin + pglob->gl_offs;
|
||||
|
||||
for(; begin != end; ++begin)
|
||||
{
|
||||
*begin = NULL;
|
||||
}
|
||||
|
||||
/* Sort, or no sort. */
|
||||
pp = (char**)new_buffer + pglob->gl_offs;
|
||||
begin = pp;
|
||||
end = begin + cMatches;
|
||||
|
||||
if(flags & GLOB_NOSORT)
|
||||
{
|
||||
/* The way we need in order to test the removal of dots in the findfile_sequence. */
|
||||
*end = NULL;
|
||||
for(begin = pp, next_str = buffer + cbPointers; begin != end; --end)
|
||||
{
|
||||
*(end - 1) = next_str;
|
||||
|
||||
/* Find the next string. */
|
||||
next_str += 1 + lstrlenA(next_str);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The normal way. */
|
||||
for(begin = pp, next_str = buffer + cbPointers; begin != end; ++begin)
|
||||
{
|
||||
*begin = next_str;
|
||||
|
||||
/* Find the next string. */
|
||||
next_str += 1 + lstrlenA(next_str);
|
||||
}
|
||||
*begin = NULL;
|
||||
}
|
||||
|
||||
/* Return results to caller. */
|
||||
pglob->gl_pathc = (int)cMatches;
|
||||
pglob->gl_matchc= (int)cMatches;
|
||||
pglob->gl_flags = 0;
|
||||
if(bMagic)
|
||||
{
|
||||
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||
}
|
||||
pglob->gl_pathv = (char**)new_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == cMatches)
|
||||
{
|
||||
result = GLOB_NOMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if(GLOB_NOMATCH == result)
|
||||
{
|
||||
if( (flags & GLOB_TILDE_CHECK) &&
|
||||
effectivePattern == szPattern3)
|
||||
{
|
||||
result = GLOB_NOMATCH;
|
||||
}
|
||||
else if(bNoMagic ||
|
||||
(flags & GLOB_NOCHECK))
|
||||
{
|
||||
const size_t effPattLen = strlen(effectivePattern);
|
||||
const size_t cbNeeded = ((2 + pglob->gl_offs) * sizeof(char*)) + (1 + effPattLen);
|
||||
char **pp = (char**)realloc(buffer, cbNeeded);
|
||||
|
||||
if(NULL == pp)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle the offsets. */
|
||||
char** begin = pp;
|
||||
char** end = pp + pglob->gl_offs;
|
||||
char* dest = (char*)(pp + 2 + pglob->gl_offs);
|
||||
|
||||
for(; begin != end; ++begin)
|
||||
{
|
||||
*begin = NULL;
|
||||
}
|
||||
|
||||
/* Synthesise the pattern result. */
|
||||
#ifdef UNIXEM_USING_SAFE_STR_FUNCTIONS
|
||||
pp[0 + pglob->gl_offs] = (strcpy_s(dest, effPattLen + 1, effectivePattern), dest);
|
||||
#else /* ? UNIXEM_USING_SAFE_STR_FUNCTIONS */
|
||||
pp[0 + pglob->gl_offs] = strcpy(dest, effectivePattern);
|
||||
#endif /* UNIXEM_USING_SAFE_STR_FUNCTIONS */
|
||||
pp[1 + pglob->gl_offs] = NULL;
|
||||
|
||||
/* Return results to caller. */
|
||||
pglob->gl_pathc = 1;
|
||||
pglob->gl_matchc= 1;
|
||||
pglob->gl_flags = 0;
|
||||
if(bMagic)
|
||||
{
|
||||
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||
}
|
||||
pglob->gl_pathv = pp;
|
||||
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(0 == result)
|
||||
{
|
||||
if((size_t)pglob->gl_matchc == maxMatches)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void globfree(glob_t *pglob)
|
||||
{
|
||||
if(pglob != NULL)
|
||||
{
|
||||
free(pglob->gl_pathv);
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ///////////////////////////// end of file //////////////////////////// */
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* File: glob.c
|
||||
*
|
||||
* Purpose: Definition of the glob() API functions for the Win32 platform.
|
||||
*
|
||||
* Created: 13th November 2002
|
||||
* Updated: 6th February 2010
|
||||
*
|
||||
* Home: http://synesis.com.au/software/
|
||||
*
|
||||
* Copyright (c) 2002-2010, Matthew Wilson and Synesis Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* - Neither the names of Matthew Wilson and Synesis Software nor the names of
|
||||
* any contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////// */
|
||||
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* Includes
|
||||
*/
|
||||
|
||||
#include <glob.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
||||
#define NUM_ELEMENTS(ar) (sizeof(ar) / sizeof(ar[0]))
|
||||
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
static char const *strrpbrk(char const *string, char const *strCharSet)
|
||||
{
|
||||
char *part = NULL;
|
||||
char const *pch;
|
||||
|
||||
for(pch = strCharSet; *pch; ++pch)
|
||||
{
|
||||
char *p = strrchr(string, *pch);
|
||||
|
||||
if(NULL != p)
|
||||
{
|
||||
if(NULL == part)
|
||||
{
|
||||
part = p;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(part < p)
|
||||
{
|
||||
part = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return part;
|
||||
}
|
||||
|
||||
/* /////////////////////////////////////////////////////////////////////////
|
||||
* API functions
|
||||
*/
|
||||
|
||||
/* It gives you back the matched contents of your pattern, so for Win32, the
|
||||
* directories must be included
|
||||
*/
|
||||
|
||||
int glob( char const *pattern
|
||||
, int flags
|
||||
#if defined(__COMO__)
|
||||
, int (*errfunc)(char const *, int)
|
||||
#else /* ? compiler */
|
||||
, const int (*errfunc)(char const *, int)
|
||||
#endif /* compiler */
|
||||
, glob_t *pglob)
|
||||
{
|
||||
int result;
|
||||
char szRelative[1 + _MAX_PATH];
|
||||
char const *file_part;
|
||||
WIN32_FIND_DATAA find_data;
|
||||
HANDLE hFind;
|
||||
char *buffer;
|
||||
char szPattern2[1 + _MAX_PATH];
|
||||
char szPattern3[1 + _MAX_PATH];
|
||||
char const *effectivePattern = pattern;
|
||||
char const *leafMost;
|
||||
const int bMagic = (NULL != strpbrk(pattern, "?*"));
|
||||
int bNoMagic = 0;
|
||||
int bMagic0;
|
||||
size_t maxMatches = ~(size_t)(0);
|
||||
|
||||
assert(NULL != pglob);
|
||||
|
||||
if(flags & GLOB_NOMAGIC)
|
||||
{
|
||||
bNoMagic = !bMagic;
|
||||
}
|
||||
|
||||
if(flags & GLOB_LIMIT)
|
||||
{
|
||||
maxMatches = (size_t)pglob->gl_matchc;
|
||||
}
|
||||
|
||||
if(flags & GLOB_TILDE)
|
||||
{
|
||||
/* Check that begins with "~/" */
|
||||
if( '~' == pattern[0] &&
|
||||
( '\0' == pattern[1] ||
|
||||
'/' == pattern[1] ||
|
||||
'\\' == pattern[1]))
|
||||
{
|
||||
DWORD dw;
|
||||
|
||||
(void)lstrcpyA(&szPattern2[0], "%HOMEDRIVE%%HOMEPATH%");
|
||||
|
||||
dw = ExpandEnvironmentStringsA(&szPattern2[0], &szPattern3[0], NUM_ELEMENTS(szPattern3) - 1);
|
||||
|
||||
if(0 != dw)
|
||||
{
|
||||
(void)lstrcpynA(&szPattern3[0] + dw - 1, &pattern[1], (int)(NUM_ELEMENTS(szPattern3) - dw));
|
||||
szPattern3[NUM_ELEMENTS(szPattern3) - 1] = '\0';
|
||||
|
||||
effectivePattern = szPattern3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file_part = strrpbrk(effectivePattern, "\\/");
|
||||
|
||||
if(NULL != file_part)
|
||||
{
|
||||
leafMost = ++file_part;
|
||||
|
||||
(void)lstrcpyA(szRelative, effectivePattern);
|
||||
szRelative[file_part - effectivePattern] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
szRelative[0] = '\0';
|
||||
leafMost = effectivePattern;
|
||||
}
|
||||
|
||||
bMagic0 = (leafMost == strpbrk(leafMost, "?*"));
|
||||
|
||||
hFind = FindFirstFileA(effectivePattern, &find_data);
|
||||
buffer = NULL;
|
||||
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
|
||||
if(0 == (flags & GLOB_DOOFFS))
|
||||
{
|
||||
pglob->gl_offs = 0;
|
||||
}
|
||||
|
||||
if(hFind == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* If this was a pattern search, and the
|
||||
* directory exists, then we return 0
|
||||
* matches, rather than GLOB_NOMATCH
|
||||
*/
|
||||
if( bMagic &&
|
||||
NULL != file_part)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NULL != errfunc)
|
||||
{
|
||||
(void)errfunc(effectivePattern, (int)GetLastError());
|
||||
}
|
||||
|
||||
result = GLOB_NOMATCH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int cbCurr = 0;
|
||||
size_t cbAlloc = 0;
|
||||
size_t cMatches = 0;
|
||||
|
||||
result = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int cch;
|
||||
size_t new_cbAlloc;
|
||||
|
||||
if( bMagic0 &&
|
||||
0 == (flags & GLOB_PERIOD))
|
||||
{
|
||||
if('.' == find_data.cFileName[0])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
#ifdef GLOB_ONLYFILE
|
||||
if(flags & GLOB_ONLYFILE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif /* GLOB_ONLYFILE */
|
||||
|
||||
if( bMagic0 &&
|
||||
GLOB_NODOTSDIRS == (flags & GLOB_NODOTSDIRS))
|
||||
{
|
||||
/* Pattern must begin with '.' to match either dots directory */
|
||||
if( 0 == lstrcmpA(".", find_data.cFileName) ||
|
||||
0 == lstrcmpA("..", find_data.cFileName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(flags & GLOB_MARK)
|
||||
{
|
||||
#if 0
|
||||
if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M')
|
||||
#endif /* 0 */
|
||||
(void)lstrcatA(find_data.cFileName, "/");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(flags & GLOB_ONLYDIR)
|
||||
{
|
||||
/* Skip all further actions, and get the next entry */
|
||||
#if 0
|
||||
if(find_data.cFileName[0] >= 'A' && find_data.cFileName[0] <= 'M')
|
||||
#endif /* 0 */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
cch = lstrlenA(find_data.cFileName);
|
||||
if(NULL != file_part)
|
||||
{
|
||||
cch += (int)(file_part - effectivePattern);
|
||||
}
|
||||
|
||||
new_cbAlloc = (size_t)cbCurr + cch + 1;
|
||||
if(new_cbAlloc > cbAlloc)
|
||||
{
|
||||
char *new_buffer;
|
||||
|
||||
new_cbAlloc *= 2;
|
||||
|
||||
new_cbAlloc = (new_cbAlloc + 31) & ~(31);
|
||||
|
||||
new_buffer = (char*)realloc(buffer, new_cbAlloc);
|
||||
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = new_buffer;
|
||||
cbAlloc = new_cbAlloc;
|
||||
}
|
||||
|
||||
(void)lstrcpynA(buffer + cbCurr, szRelative, 1 + (int)(file_part - effectivePattern));
|
||||
(void)lstrcatA(buffer + cbCurr, find_data.cFileName);
|
||||
cbCurr += cch + 1;
|
||||
|
||||
++cMatches;
|
||||
}
|
||||
while(FindNextFile(hFind, &find_data) && cMatches != maxMatches);
|
||||
|
||||
(void)FindClose(hFind);
|
||||
|
||||
if(result == 0)
|
||||
{
|
||||
/* Now expand the buffer, to fit in all the pointers. */
|
||||
size_t cbPointers = (1 + cMatches + pglob->gl_offs) * sizeof(char*);
|
||||
char *new_buffer = (char*)realloc(buffer, cbAlloc + cbPointers);
|
||||
|
||||
if(new_buffer == NULL)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
char **pp;
|
||||
char **begin;
|
||||
char **end;
|
||||
char *next_str;
|
||||
|
||||
buffer = new_buffer;
|
||||
|
||||
(void)memmove(new_buffer + cbPointers, new_buffer, cbAlloc);
|
||||
|
||||
/* Handle the offsets. */
|
||||
begin = (char**)new_buffer;
|
||||
end = begin + pglob->gl_offs;
|
||||
|
||||
for(; begin != end; ++begin)
|
||||
{
|
||||
*begin = NULL;
|
||||
}
|
||||
|
||||
/* Sort, or no sort. */
|
||||
pp = (char**)new_buffer + pglob->gl_offs;
|
||||
begin = pp;
|
||||
end = begin + cMatches;
|
||||
|
||||
if(flags & GLOB_NOSORT)
|
||||
{
|
||||
/* The way we need in order to test the removal of dots in the findfile_sequence. */
|
||||
*end = NULL;
|
||||
for(begin = pp, next_str = buffer + cbPointers; begin != end; --end)
|
||||
{
|
||||
*(end - 1) = next_str;
|
||||
|
||||
/* Find the next string. */
|
||||
next_str += 1 + lstrlenA(next_str);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The normal way. */
|
||||
for(begin = pp, next_str = buffer + cbPointers; begin != end; ++begin)
|
||||
{
|
||||
*begin = next_str;
|
||||
|
||||
/* Find the next string. */
|
||||
next_str += 1 + lstrlenA(next_str);
|
||||
}
|
||||
*begin = NULL;
|
||||
}
|
||||
|
||||
/* Return results to caller. */
|
||||
pglob->gl_pathc = (int)cMatches;
|
||||
pglob->gl_matchc= (int)cMatches;
|
||||
pglob->gl_flags = 0;
|
||||
if(bMagic)
|
||||
{
|
||||
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||
}
|
||||
pglob->gl_pathv = (char**)new_buffer;
|
||||
}
|
||||
}
|
||||
|
||||
if(0 == cMatches)
|
||||
{
|
||||
result = GLOB_NOMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if(GLOB_NOMATCH == result)
|
||||
{
|
||||
if( (flags & GLOB_TILDE_CHECK) &&
|
||||
effectivePattern == szPattern3)
|
||||
{
|
||||
result = GLOB_NOMATCH;
|
||||
}
|
||||
else if(bNoMagic ||
|
||||
(flags & GLOB_NOCHECK))
|
||||
{
|
||||
const size_t effPattLen = strlen(effectivePattern);
|
||||
const size_t cbNeeded = ((2 + pglob->gl_offs) * sizeof(char*)) + (1 + effPattLen);
|
||||
char **pp = (char**)realloc(buffer, cbNeeded);
|
||||
|
||||
if(NULL == pp)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Handle the offsets. */
|
||||
char** begin = pp;
|
||||
char** end = pp + pglob->gl_offs;
|
||||
char* dest = (char*)(pp + 2 + pglob->gl_offs);
|
||||
|
||||
for(; begin != end; ++begin)
|
||||
{
|
||||
*begin = NULL;
|
||||
}
|
||||
|
||||
/* Synthesise the pattern result. */
|
||||
#ifdef UNIXEM_USING_SAFE_STR_FUNCTIONS
|
||||
pp[0 + pglob->gl_offs] = (strcpy_s(dest, effPattLen + 1, effectivePattern), dest);
|
||||
#else /* ? UNIXEM_USING_SAFE_STR_FUNCTIONS */
|
||||
pp[0 + pglob->gl_offs] = strcpy(dest, effectivePattern);
|
||||
#endif /* UNIXEM_USING_SAFE_STR_FUNCTIONS */
|
||||
pp[1 + pglob->gl_offs] = NULL;
|
||||
|
||||
/* Return results to caller. */
|
||||
pglob->gl_pathc = 1;
|
||||
pglob->gl_matchc= 1;
|
||||
pglob->gl_flags = 0;
|
||||
if(bMagic)
|
||||
{
|
||||
pglob->gl_flags |= GLOB_MAGCHAR;
|
||||
}
|
||||
pglob->gl_pathv = pp;
|
||||
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(0 == result)
|
||||
{
|
||||
if((size_t)pglob->gl_matchc == maxMatches)
|
||||
{
|
||||
result = GLOB_NOSPACE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void globfree(glob_t *pglob)
|
||||
{
|
||||
if(pglob != NULL)
|
||||
{
|
||||
free(pglob->gl_pathv);
|
||||
pglob->gl_pathc = 0;
|
||||
pglob->gl_pathv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ///////////////////////////// end of file //////////////////////////// */
|
||||
|
@@ -1,212 +1,212 @@
|
||||
// ==============================================================
|
||||
// This file is part of Glest Shared Library (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martio Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
#include "platform_util.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
// ==============================================================
|
||||
// This file is part of Glest Shared Library (www.glest.org)
|
||||
//
|
||||
// Copyright (C) 2001-2008 Martio Figueroa
|
||||
//
|
||||
// You can redistribute this code and/or modify it under
|
||||
// the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version
|
||||
// ==============================================================
|
||||
|
||||
#include "platform_util.h"
|
||||
|
||||
#include <io.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include <string.h>
|
||||
#include "SDL_syswm.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace Shared::Util;
|
||||
using namespace std;
|
||||
|
||||
namespace Shared { namespace Platform {
|
||||
|
||||
// =====================================================
|
||||
// class PlatformExceptionHandler
|
||||
// =====================================================
|
||||
|
||||
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
|
||||
|
||||
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
|
||||
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
HANDLE hFile = CreateFile(
|
||||
thisPointer->dumpFileName.c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
|
||||
|
||||
lExceptionInformation.ThreadId= GetCurrentThreadId();
|
||||
lExceptionInformation.ExceptionPointers= pointers;
|
||||
lExceptionInformation.ClientPointers= false;
|
||||
#include "leak_dumper.h"
|
||||
|
||||
using namespace Shared::Util;
|
||||
using namespace std;
|
||||
|
||||
namespace Shared { namespace Platform {
|
||||
|
||||
// =====================================================
|
||||
// class PlatformExceptionHandler
|
||||
// =====================================================
|
||||
|
||||
PlatformExceptionHandler *PlatformExceptionHandler::thisPointer= NULL;
|
||||
|
||||
LONG WINAPI PlatformExceptionHandler::handler(LPEXCEPTION_POINTERS pointers){
|
||||
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
HANDLE hFile = CreateFile(
|
||||
thisPointer->dumpFileName.c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION lExceptionInformation;
|
||||
|
||||
lExceptionInformation.ThreadId= GetCurrentThreadId();
|
||||
lExceptionInformation.ExceptionPointers= pointers;
|
||||
lExceptionInformation.ClientPointers= false;
|
||||
|
||||
#if defined(__WIN32__) && !defined(__GNUC__)
|
||||
MiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MiniDumpNormal,
|
||||
&lExceptionInformation,
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
thisPointer->handle();
|
||||
#endif
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void PlatformExceptionHandler::install(string dumpFileName){
|
||||
thisPointer= this;
|
||||
this->dumpFileName= dumpFileName;
|
||||
SetUnhandledExceptionFilter(handler);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class Misc
|
||||
// =====================================================
|
||||
|
||||
//void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) {
|
||||
// // Get the current video hardware information
|
||||
// //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
|
||||
// //colorBits = vidInfo->vfmt->BitsPerPixel;
|
||||
// //screenWidth = vidInfo->current_w;
|
||||
//
|
||||
///*
|
||||
// //screenHeight = vidInfo->current_h;
|
||||
// int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
// // height
|
||||
// int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
//
|
||||
// printf("cx = %d, cy = %d\n",cx,cy);
|
||||
//
|
||||
// if(cx > screenWidth) {
|
||||
// screenWidth = cx;
|
||||
// screenHeight = cy;
|
||||
// }
|
||||
//*/
|
||||
// int iMaxWidth = -1;
|
||||
// int iMaxHeight = -1;
|
||||
// int iMaxBits = -1;
|
||||
//
|
||||
// DEVMODE devMode;
|
||||
// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
|
||||
//
|
||||
// //printf("devMode.dmPelsWidth = %d, devMode.dmPelsHeight = %d, devMode.dmBitsPerPel = %d\n",devMode.dmPelsWidth,devMode.dmPelsHeight,devMode.dmBitsPerPel);
|
||||
//
|
||||
// if(devMode.dmPelsWidth > iMaxWidth) {
|
||||
// iMaxWidth = devMode.dmPelsWidth;
|
||||
// iMaxHeight = devMode.dmPelsHeight;
|
||||
// iMaxBits = devMode.dmBitsPerPel;
|
||||
// //devMode.dmDisplayFrequency=refreshFrequency;
|
||||
// }
|
||||
// }
|
||||
// if(iMaxWidth > 0) {
|
||||
// colorBits = iMaxBits;
|
||||
// screenWidth = iMaxWidth;
|
||||
// screenHeight = iMaxHeight;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
|
||||
// DEVMODE devMode;
|
||||
//
|
||||
// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
|
||||
// if (devMode.dmPelsWidth== resW &&
|
||||
// devMode.dmPelsHeight== resH &&
|
||||
// devMode.dmBitsPerPel== colorBits){
|
||||
//
|
||||
// devMode.dmDisplayFrequency=refreshFrequency;
|
||||
//
|
||||
// LONG result= ChangeDisplaySettings(&devMode, 0);
|
||||
// if(result == DISP_CHANGE_SUCCESSFUL){
|
||||
// return true;
|
||||
// }
|
||||
// else{
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//void restoreVideoMode(bool exitingApp) {
|
||||
// int dispChangeErr= ChangeDisplaySettings(NULL, 0);
|
||||
// assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
|
||||
//}
|
||||
|
||||
void message(string message){
|
||||
std::cerr << "******************************************************\n";
|
||||
std::cerr << " " << message << "\n";
|
||||
std::cerr << "******************************************************\n";
|
||||
|
||||
MessageBox(NULL, message.c_str(), "Message", MB_OK);
|
||||
}
|
||||
|
||||
bool ask(string message){
|
||||
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
|
||||
}
|
||||
|
||||
void exceptionMessage(const exception &excp){
|
||||
string message, title;
|
||||
showCursor(true);
|
||||
|
||||
message+= "ERROR(S):\n\n";
|
||||
message+= excp.what();
|
||||
|
||||
title= "Error: Unhandled Exception";
|
||||
printf("Error detected with text: %s\n",message.c_str());
|
||||
|
||||
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
//int getScreenW(){
|
||||
// return GetSystemMetrics(SM_CXSCREEN);
|
||||
//}
|
||||
|
||||
//int getScreenH(){
|
||||
// return GetSystemMetrics(SM_CYSCREEN);
|
||||
//}
|
||||
|
||||
#if defined(__WIN32__) && !defined(__GNUC__)
|
||||
MiniDumpWriteDump(
|
||||
GetCurrentProcess(),
|
||||
GetCurrentProcessId(),
|
||||
hFile,
|
||||
MiniDumpNormal,
|
||||
&lExceptionInformation,
|
||||
NULL,
|
||||
NULL );
|
||||
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
thisPointer->handle();
|
||||
#endif
|
||||
//printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
void PlatformExceptionHandler::install(string dumpFileName){
|
||||
thisPointer= this;
|
||||
this->dumpFileName= dumpFileName;
|
||||
SetUnhandledExceptionFilter(handler);
|
||||
}
|
||||
|
||||
// =====================================================
|
||||
// class Misc
|
||||
// =====================================================
|
||||
|
||||
//void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight) {
|
||||
// // Get the current video hardware information
|
||||
// //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
|
||||
// //colorBits = vidInfo->vfmt->BitsPerPixel;
|
||||
// //screenWidth = vidInfo->current_w;
|
||||
//
|
||||
///*
|
||||
// //screenHeight = vidInfo->current_h;
|
||||
// int cx = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
// // height
|
||||
// int cy = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
//
|
||||
// printf("cx = %d, cy = %d\n",cx,cy);
|
||||
//
|
||||
// if(cx > screenWidth) {
|
||||
// screenWidth = cx;
|
||||
// screenHeight = cy;
|
||||
// }
|
||||
//*/
|
||||
// int iMaxWidth = -1;
|
||||
// int iMaxHeight = -1;
|
||||
// int iMaxBits = -1;
|
||||
//
|
||||
// DEVMODE devMode;
|
||||
// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
|
||||
//
|
||||
// //printf("devMode.dmPelsWidth = %d, devMode.dmPelsHeight = %d, devMode.dmBitsPerPel = %d\n",devMode.dmPelsWidth,devMode.dmPelsHeight,devMode.dmBitsPerPel);
|
||||
//
|
||||
// if(devMode.dmPelsWidth > iMaxWidth) {
|
||||
// iMaxWidth = devMode.dmPelsWidth;
|
||||
// iMaxHeight = devMode.dmPelsHeight;
|
||||
// iMaxBits = devMode.dmBitsPerPel;
|
||||
// //devMode.dmDisplayFrequency=refreshFrequency;
|
||||
// }
|
||||
// }
|
||||
// if(iMaxWidth > 0) {
|
||||
// colorBits = iMaxBits;
|
||||
// screenWidth = iMaxWidth;
|
||||
// screenHeight = iMaxHeight;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//bool changeVideoMode(int resW, int resH, int colorBits, int refreshFrequency){
|
||||
// DEVMODE devMode;
|
||||
//
|
||||
// for (int i=0; EnumDisplaySettings(NULL, i, &devMode) ;i++){
|
||||
// if (devMode.dmPelsWidth== resW &&
|
||||
// devMode.dmPelsHeight== resH &&
|
||||
// devMode.dmBitsPerPel== colorBits){
|
||||
//
|
||||
// devMode.dmDisplayFrequency=refreshFrequency;
|
||||
//
|
||||
// LONG result= ChangeDisplaySettings(&devMode, 0);
|
||||
// if(result == DISP_CHANGE_SUCCESSFUL){
|
||||
// return true;
|
||||
// }
|
||||
// else{
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
//}
|
||||
//
|
||||
//void restoreVideoMode(bool exitingApp) {
|
||||
// int dispChangeErr= ChangeDisplaySettings(NULL, 0);
|
||||
// assert(dispChangeErr==DISP_CHANGE_SUCCESSFUL);
|
||||
//}
|
||||
|
||||
void message(string message){
|
||||
std::cerr << "******************************************************\n";
|
||||
std::cerr << " " << message << "\n";
|
||||
std::cerr << "******************************************************\n";
|
||||
|
||||
MessageBox(NULL, message.c_str(), "Message", MB_OK);
|
||||
}
|
||||
|
||||
bool ask(string message){
|
||||
return MessageBox(NULL, message.c_str(), "Confirmation", MB_YESNO)==IDYES;
|
||||
}
|
||||
|
||||
void exceptionMessage(const exception &excp){
|
||||
string message, title;
|
||||
showCursor(true);
|
||||
|
||||
message+= "ERROR(S):\n\n";
|
||||
message+= excp.what();
|
||||
|
||||
title= "Error: Unhandled Exception";
|
||||
printf("Error detected with text: %s\n",message.c_str());
|
||||
|
||||
MessageBox(NULL, message.c_str(), title.c_str(), MB_ICONSTOP | MB_OK | MB_TASKMODAL);
|
||||
}
|
||||
|
||||
//int getScreenW(){
|
||||
// return GetSystemMetrics(SM_CXSCREEN);
|
||||
//}
|
||||
|
||||
//int getScreenH(){
|
||||
// return GetSystemMetrics(SM_CYSCREEN);
|
||||
//}
|
||||
|
||||
// This lets us set the SDL Window Icon in Windows
|
||||
// since its a console application
|
||||
HICON icon;
|
||||
HICON icon;
|
||||
|
||||
void init_win32() {
|
||||
HINSTANCE handle = ::GetModuleHandle(NULL);
|
||||
icon = ::LoadIcon(handle, "IDI_ICON1");
|
||||
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_VERSION(&wminfo.version)
|
||||
if (SDL_GetWMInfo(&wminfo) != 1)
|
||||
{
|
||||
// error: wrong SDL version
|
||||
}
|
||||
|
||||
HWND hwnd = wminfo.window;
|
||||
|
||||
::SetClassLong(hwnd, GCL_HICON, (LONG) icon);
|
||||
}
|
||||
void done_win32() {
|
||||
::DestroyIcon(icon);
|
||||
void init_win32() {
|
||||
HINSTANCE handle = ::GetModuleHandle(NULL);
|
||||
icon = ::LoadIcon(handle, "IDI_ICON1");
|
||||
|
||||
SDL_SysWMinfo wminfo;
|
||||
SDL_VERSION(&wminfo.version)
|
||||
if (SDL_GetWMInfo(&wminfo) != 1)
|
||||
{
|
||||
// error: wrong SDL version
|
||||
}
|
||||
|
||||
HWND hwnd = wminfo.window;
|
||||
|
||||
::SetClassLong(hwnd, GCL_HICON, (LONG) icon);
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
void done_win32() {
|
||||
::DestroyIcon(icon);
|
||||
}
|
||||
|
||||
}}//end namespace
|
||||
|
Reference in New Issue
Block a user