Exemplo n.º 1
0
Arquivo: sql.c Projeto: joltcan/gammu
static SQL_Error SMSDSQL_Query(GSM_SMSDConfig * Config, const char *query, SQL_result * res)
{
	SQL_Error error = SQL_TIMEOUT;
	int attempts = 1;
	struct GSM_SMSDdbobj *db = Config->db;

	for (attempts = 1; attempts <= Config->backend_retries; attempts++) {
		SMSD_Log(DEBUG_SQL, Config, "Execute SQL: %s", query);
		error = db->Query(Config, query, res);
		if (error == SQL_OK) {
			return error;
		}

		if (error != SQL_TIMEOUT){
			SMSD_Log(DEBUG_INFO, Config, "SQL failure: %d", error);
			return error;
		}

		SMSD_Log(DEBUG_INFO, Config, "SQL failed (timeout): %s", query);
		/* We will try to reconnect */
		SMSD_Log(DEBUG_INFO, Config, "reconnecting to database!");
		while (error != SQL_OK && attempts < Config->backend_retries) {
			SMSD_Log(DEBUG_INFO, Config, "Reconnecting after %d seconds...", attempts * attempts);
			sleep(attempts * attempts);
			db->Free(Config);
			error = db->Connect(Config);
			attempts++;
		}
	}
	return error;
}
Exemplo n.º 2
0
/* [Re]connects to database */
static GSM_Error SMSDPgSQL_Connect(GSM_SMSDConfig * Config)
{
	unsigned char buf[400];
	PGresult *Res;

	unsigned int port = 5432;
	char *pport;

	pport = strstr(Config->host, ":");
	if (pport) {
		*pport++ = '\0';
		port = atoi(pport);
	}

	sprintf(buf, "host = '%s' user = '******' password = '******' dbname = '%s' port = %d", Config->host, Config->user, Config->password, Config->database, port);

	SMSDPgSQL_Free(Config);
	Config->conn.pg = PQconnectdb(buf);
	if (PQstatus(Config->conn.pg) != CONNECTION_OK) {
		SMSD_Log(DEBUG_ERROR, Config, "Error connecting to database: %s", PQerrorMessage(Config->conn.pg));
		PQfinish(Config->conn.pg);
		return ERR_DB_CONNECT;
	}

	Res = PQexec(Config->conn.pg, "SET NAMES UTF8");
	PQclear(Res);
	SMSD_Log(DEBUG_INFO, Config, "Connected to database: %s on %s. Server version: %d Protocol: %d",
		 PQdb(Config->conn.pg), PQhost(Config->conn.pg), PQserverVersion(Config->conn.pg), PQprotocolVersion(Config->conn.pg));

	return ERR_NONE;
}
Exemplo n.º 3
0
static SQL_Error SMSDSQL_Query(GSM_SMSDConfig * Config, const char *query, SQL_result * res)
{
	SQL_Error error = SQL_TIMEOUT;
	int attempts;
	struct GSM_SMSDdbobj *db = Config->db;

	for (attempts = 1; attempts <= Config->backend_retries; attempts++) {
		SMSD_Log(DEBUG_SQL, Config, "Execute SQL: %s", query);
		error = db->Query(Config, query, res);
		if (error == SQL_OK) {
			return error;
		}

		if (error != SQL_TIMEOUT){
			SMSD_Log(DEBUG_INFO, Config, "SQL failure: %d", error);
			return error;
		}

		SMSD_Log(DEBUG_INFO, Config, "SQL failed (timeout): %s", query);
		/* We will try to reconnect */
		error = SMSDSQL_Reconnect(Config);
		if (error != SQL_OK) {
			break;
		}
	}
	return error;
}
Exemplo n.º 4
0
static void SMSDPgSQL_LogError(GSM_SMSDConfig * Config, PGresult * Res)
{
	if (Res == NULL) {
		SMSD_Log(DEBUG_INFO, Config, "Error: %s", PQerrorMessage(Config->conn.pg));
	} else {
		SMSD_Log(DEBUG_INFO, Config, "Error: %s", PQresultErrorMessage(Res));
	}
}
Exemplo n.º 5
0
Arquivo: sql.c Projeto: joltcan/gammu
/* Connects to database */
static GSM_Error SMSDSQL_Init(GSM_SMSDConfig * Config)
{
	SQL_result res;
	int version;
	GSM_Error error;
	struct GSM_SMSDdbobj *db;
	const char *escape_char;
	char buffer[100];

#ifdef WIN32
	_tzset();
#else
	tzset();
#endif

	db = Config->db;

	if (db->Connect(Config) != SQL_OK)
		return ERR_UNKNOWN;

	error = SMSDSQL_CheckTable(Config, "outbox");
	if (error != ERR_NONE)
		return error;
	error = SMSDSQL_CheckTable(Config, "outbox_multipart");
	if (error != ERR_NONE)
		return error;
	error = SMSDSQL_CheckTable(Config, "sentitems");
	if (error != ERR_NONE)
		return error;
	error = SMSDSQL_CheckTable(Config, "inbox");
	if (error != ERR_NONE)
		return error;

	escape_char = SMSDSQL_EscapeChar(Config);

	sprintf(buffer, "SELECT %sVersion%s FROM gammu", escape_char, escape_char);
	if (SMSDSQL_Query(Config, buffer, &res) != SQL_OK) {
		db->Free(Config);
		return ERR_UNKNOWN;
	}
	if (db->NextRow(Config, &res) != 1) {
		SMSD_Log(DEBUG_ERROR, Config, "Failed to seek to first row!");
		db->FreeResult(Config, &res);
		db->Free(Config);
		return ERR_UNKNOWN;
	}
	version = db->GetNumber(Config, &res, 0);
	db->FreeResult(Config, &res);
	if (SMSD_CheckDBVersion(Config, version) != ERR_NONE) {
		db->Free(Config);
		return ERR_UNKNOWN;
	}

	SMSD_Log(DEBUG_INFO, Config, "Connected to Database %s: %s on %s", Config->driver, Config->database, Config->host);

	return ERR_NONE;
}
Exemplo n.º 6
0
Arquivo: dbi.c Projeto: Bradan/gammu
static void SMSDDBI_LogError(GSM_SMSDConfig * Config)
{
	int rc;
	const char *msg;
	rc = dbi_conn_error(Config->conn.dbi, &msg);
	if (rc == -1) {
		SMSD_Log(DEBUG_ERROR, Config, "Unknown DBI error!");
	} else {
		SMSD_Log(DEBUG_ERROR, Config, "DBI error %d: %s", rc, msg);
	}
}
Exemplo n.º 7
0
Arquivo: odbc.c Projeto: Bakus/gammu
const char *SMSDODBC_GetString(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	SQLLEN sqllen;
	int size;
	SQLRETURN ret;
	char shortbuffer[1];

	if (field > SMSD_ODBC_MAX_RETURN_STRINGS) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, too many fields!", field);
		return NULL;
	}

	/* Figure out string length */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, shortbuffer, 0, &sqllen);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string,0) failed");
		return NULL;
	}

	/*
	 * This hack seems to be needed to avoid type breakage on Win64, don't ask me why.
	 *
	 * Might be actually bug in MinGW compiler, but when using SQLLEN type bellow
	 * anything fails (it does not match to SQL_NULL_DATA and realloc always fails).
	 */
	size = sqllen;

	/* Did not we get NULL? */
	if (size == SQL_NULL_DATA) {
		SMSD_Log(DEBUG_SQL, Config, "Field %d returning NULL", field);
		return NULL;
	}

	/* Allocate string */
	Config->conn.odbc.retstr[field] = realloc(Config->conn.odbc.retstr[field], size + 1);
	if (Config->conn.odbc.retstr[field] == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, failed to allocate %d bytes of memory", field, size + 1);
		return NULL;
	}

	/* Actually grab result from database */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, Config->conn.odbc.retstr[field], size + 1, &sqllen);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string) failed");
		return NULL;
	}

	SMSD_Log(DEBUG_SQL, Config, "Field %d returning string \"%s\"", field, Config->conn.odbc.retstr[field]);

	return Config->conn.odbc.retstr[field];
}
Exemplo n.º 8
0
Arquivo: dbi.c Projeto: Bradan/gammu
gboolean SMSDDBI_GetBool(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	unsigned int type;
	const char *value;
	int num;

	field++;
	type = dbi_result_get_field_type_idx(res->dbi, field);

	switch (type) {
		case DBI_TYPE_INTEGER:
		case DBI_TYPE_DECIMAL:
#ifdef DBI_TYPE_XDECIMAL
		case DBI_TYPE_XDECIMAL:
#endif
			num = SMSDDBI_GetNumber(Config, res, field);
			if (num == -1) {
				return -1;
			} else if (num == 0) {
				return FALSE;
			} else {
				return TRUE;
			}
		case DBI_TYPE_STRING:
			value = dbi_result_get_string_idx(res->dbi, field);
			return GSM_StringToBool(value);
		case DBI_TYPE_ERROR:
		default:
			SMSD_Log(DEBUG_ERROR, Config, "Wrong field type for boolean from DBI: %d", type);
			return -1;
	}
}
Exemplo n.º 9
0
Arquivo: dbi.c Projeto: Bradan/gammu
time_t SMSDDBI_GetDate(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	unsigned int type;
	const char *date;

	field++;
	type = dbi_result_get_field_type_idx(res->dbi, field);

	switch (type) {
		case DBI_TYPE_INTEGER:
		case DBI_TYPE_DECIMAL:
#ifdef DBI_TYPE_XDECIMAL
		case DBI_TYPE_XDECIMAL:
#endif
			return SMSDDBI_GetNumber(Config, res, field);
		case DBI_TYPE_STRING:
			date = dbi_result_get_string_idx(res->dbi, field);
			return SMSDSQL_ParseDate(Config, date);
		case DBI_TYPE_DATETIME:
			return dbi_result_get_datetime_idx(res->dbi, field);
		case DBI_TYPE_ERROR:
		default:
			SMSD_Log(DEBUG_ERROR, Config, "Wrong field type for date from DBI: %d", type);
			return -1;
	}
}
Exemplo n.º 10
0
Arquivo: odbc.c Projeto: liyvhg/gammu
static void SMSDODBC_LogError(GSM_SMSDConfig * Config, SQLRETURN origret, SQLSMALLINT handle_type, SQLHANDLE handle, const char *message)
{
	SQLSMALLINT	 i = 0;
	SQLINTEGER	 native;
	SQLCHAR	 state[ 7 ];
	SQLCHAR	 text[256];
	SQLSMALLINT	 len;
	SQLRETURN	 ret;

	SMSD_Log(DEBUG_ERROR, Config, "%s, Code = %d, ODBC diagnostics:", message, (int)origret);

	do {
		ret = SQLGetDiagRec(handle_type, handle, ++i, state, &native, text, sizeof(text), &len );
		if (SQL_SUCCEEDED(ret)) {
			SMSD_Log(DEBUG_ERROR, Config, "%s:%ld:%ld:%s\n", state, (long)i, (long)native, text);
		}
	} while (ret == SQL_SUCCESS);
}
Exemplo n.º 11
0
static SQL_Error SMSDSQL_Reconnect(GSM_SMSDConfig * Config)
{
	SQL_Error error = SQL_TIMEOUT;
	int attempts;
	struct GSM_SMSDdbobj *db = Config->db;

	SMSD_Log(DEBUG_INFO, Config, "Reconnecting to the database!");
	for (attempts = 1; attempts <= Config->backend_retries; attempts++) {
		SMSD_Log(DEBUG_INFO, Config, "Reconnecting after %d seconds...", attempts * attempts);
		sleep(attempts * attempts);
		db->Free(Config);
		error = db->Connect(Config);
		if (error == SQL_OK) {
			return error;
		}
	}
	return error;
}
Exemplo n.º 12
0
Arquivo: dbi.c Projeto: Bradan/gammu
static GSM_Error SMSDDBI_Query(GSM_SMSDConfig * Config, const char *query, SQL_result * res)
{
	const char *msg;
	int rc;

	res->dbi = NULL;

	SMSD_Log(DEBUG_SQL, Config, "Execute SQL: %s", query);
	res->dbi = dbi_conn_query(Config->conn.dbi, query);
	if (res->dbi != NULL)
		return ERR_NONE;

	SMSD_Log(DEBUG_INFO, Config, "SQL failed: %s", query);
	/* Black magic to decide whether we should bail out or attempt to retry */
	rc = dbi_conn_error(Config->conn.dbi, &msg);
	if (rc != -1) {
		SMSD_Log(DEBUG_INFO, Config, "SQL failure: %s", msg);
		if (strstr(msg, "syntax") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "violation") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "violates") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "SQL error") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "duplicate") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "unique") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "need to rewrite") != NULL) {
			return ERR_SQL;
		}
		if (strstr(msg, "locked") != NULL) {
			return ERR_DB_TIMEOUT;
		}
	}
	return ERR_DB_TIMEOUT;
}
Exemplo n.º 13
0
Arquivo: mysql.c Projeto: gammu/gammu
static GSM_Error SMSDMySQL_Connect(GSM_SMSDConfig * Config)
{

	unsigned int port = 0;
	int error;
	char *pport;
	char *socketname = NULL;

	pport = strstr(Config->host, ":");
	if (pport) {
		*pport++ = '\0';
		/* Is it port or socket? */
		if (strchr("0123456798", *pport) != NULL) {
			port = atoi(pport);
		} else {
			socketname = pport;
		}
	}
	if (Config->conn.my == NULL) {
		Config->conn.my = malloc(sizeof(MYSQL));
		mysql_init(Config->conn.my);
	}
	if (Config->conn.my == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "MySQL allocation failed!");
		return ERR_DB_DRIVER;
	}
	if (!mysql_real_connect(Config->conn.my, Config->host, Config->user, Config->password, Config->database, port, socketname, 0)) {
		SMSD_Log(DEBUG_ERROR, Config, "Error connecting to database!");
		SMSDMySQL_LogError(Config);
		error = mysql_errno(Config->conn.my);
		if (error == 2006 || error == 2003 || error == 2002) { /* cant connect through socket */
			return ERR_DB_TIMEOUT;
		}
		return ERR_DB_CONNECT;
	}

	/* Try using utf8mb4 if MySQL server supports it */
	if (mysql_query(Config->conn.my, "SET NAMES utf8mb4;") != 0) {
		mysql_query(Config->conn.my, "SET NAMES utf8;");
	}
	SMSD_Log(DEBUG_INFO, Config, "Connected to Database: %s on %s", Config->database, Config->host);
	return ERR_NONE;
}
Exemplo n.º 14
0
Arquivo: mysql.c Projeto: gammu/gammu
static int SMSDMySQL_LogError(GSM_SMSDConfig * Config)
{
	int mysql_err;

	mysql_err = mysql_errno(Config->conn.my);

	SMSD_Log(DEBUG_ERROR, Config, "Error code: %d, Error: %s", mysql_err, mysql_error(Config->conn.my));

	return mysql_err;
}
Exemplo n.º 15
0
Arquivo: odbc.c Projeto: liyvhg/gammu
const char *SMSDODBC_GetString(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	SQLLEN size;
	SQLRETURN ret;
	char shortbuffer[1];

	if (field > SMSD_ODBC_MAX_RETURN_STRINGS) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, too many fields!", field);
		return NULL;
	}

	/* Figure out string length */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, shortbuffer, 0, &size);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string,0) failed");
		return NULL;
	}

	/* Did not we get NULL? */
	if (size == SQL_NULL_DATA) {
		SMSD_Log(DEBUG_SQL, Config, "Field %d returning NULL", field);
		return NULL;
	}

	/* Allocate string */
	Config->conn.odbc.retstr[field] = realloc(Config->conn.odbc.retstr[field], size + 1);
	if (Config->conn.odbc.retstr[field] == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "Field %d returning NULL, failed to allocate %ld bytes of memory", field, (long)(size + 1));
		return NULL;
	}

	/* Actually grab result from database */
	ret = SQLGetData(res->odbc, field + 1, SQL_C_CHAR, Config->conn.odbc.retstr[field], size + 1, &size);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(string) failed");
		return NULL;
	}

	SMSD_Log(DEBUG_SQL, Config, "Field %d returning string \"%s\"", field, Config->conn.odbc.retstr[field]);

	return Config->conn.odbc.retstr[field];
}
Exemplo n.º 16
0
Arquivo: dbi.c Projeto: Bradan/gammu
long long SMSDDBI_GetNumber(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field)
{
	unsigned int type;

	field++;
	type = dbi_result_get_field_type_idx(res->dbi, field);

	switch (type) {
		case DBI_TYPE_INTEGER:
			type = dbi_result_get_field_attribs_idx(res->dbi, field);
			if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE1) {
				return dbi_result_get_int_idx(res->dbi, field);
			} else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE2) {
				return dbi_result_get_int_idx(res->dbi, field);
			} else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE3) {
				return dbi_result_get_int_idx(res->dbi, field);
			} else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE4) {
				return dbi_result_get_int_idx(res->dbi, field);
			} else if ((type & DBI_INTEGER_SIZEMASK) == DBI_INTEGER_SIZE8) {
				return dbi_result_get_longlong_idx(res->dbi, field);
			}
			SMSD_Log(DEBUG_ERROR, Config, "Wrong integer field subtype from DBI: %d", type);
			return -1;
		case DBI_TYPE_DECIMAL:
			type = dbi_result_get_field_attribs_idx(res->dbi, field);
			if ((type & DBI_DECIMAL_SIZEMASK) == DBI_DECIMAL_SIZE4) {
				return dbi_result_get_int_idx(res->dbi, field);
			} else if ((type & DBI_DECIMAL_SIZEMASK) == DBI_DECIMAL_SIZE8) {
				return dbi_result_get_longlong_idx(res->dbi, field);
			}
			SMSD_Log(DEBUG_ERROR, Config, "Wrong decimal field subtype from DBI: %d", type);
			return -1;
#ifdef DBI_TYPE_XDECIMAL
		case DBI_TYPE_XDECIMAL:
			return dbi_result_get_as_longlong_idx(res->dbi, field);
#endif
		default:
			SMSD_Log(DEBUG_ERROR, Config, "Wrong field type for number (not INTEGER nor DECIMAL) from DBI: %d", type);
			return -1;
	}
}
Exemplo n.º 17
0
Arquivo: sql.c Projeto: joltcan/gammu
/* Disconnects from a database */
static GSM_Error SMSDSQL_Free(GSM_SMSDConfig * Config)
{
	int i;
	SMSD_Log(DEBUG_SQL, Config, "Disconnecting from SQL database.");
	Config->db->Free(Config);
	/* free configuration */
	for(i = 0; i < SQL_QUERY_LAST_NO; i++){
		free(Config->SMSDSQL_queries[i]);
		Config->SMSDSQL_queries[i] = NULL;
	}
	return ERR_NONE;
}
Exemplo n.º 18
0
Arquivo: odbc.c Projeto: liyvhg/gammu
/* Connects to database */
static GSM_Error SMSDODBC_Connect(GSM_SMSDConfig * Config)
{
	SQLRETURN ret;
	int field;
	char driver_name[1000];
	SQLSMALLINT len;

	for (field = 0; field < SMSD_ODBC_MAX_RETURN_STRINGS; field++) {
		Config->conn.odbc.retstr[field] = NULL;
	}

	ret = SQLAllocHandle (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &Config->conn.odbc.env);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_ENV, Config->conn.odbc.env, "SQLAllocHandle(ENV) failed");
		return ERR_DB_DRIVER;
	}

	ret = SQLSetEnvAttr (Config->conn.odbc.env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_ENV, Config->conn.odbc.env, "SQLSetEnvAttr failed");
		return ERR_DB_CONFIG;
	}

	ret = SQLAllocHandle (SQL_HANDLE_DBC, Config->conn.odbc.env, &Config->conn.odbc.dbc);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_ENV, Config->conn.odbc.env, "SQLAllocHandle(DBC) failed");
		return ERR_DB_CONFIG;
	}

	ret = SQLConnect(Config->conn.odbc.dbc,
			  (SQLCHAR*)Config->host, SQL_NTS,
			  (SQLCHAR*)Config->user, SQL_NTS,
			  (SQLCHAR*)Config->password, SQL_NTS);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_DBC, Config->conn.odbc.dbc, "SQLConnect failed");
		return ERR_DB_CONNECT;
	}

	ret = SQLGetInfo(Config->conn.odbc.dbc, SQL_DRIVER_NAME, driver_name, sizeof(driver_name), &len);
	if (!SQL_SUCCEEDED(ret)) {
		SMSDODBC_LogError(Config, ret, SQL_HANDLE_DBC, Config->conn.odbc.dbc, "SQLGetInfo failed");
		return ERR_DB_CONNECT;
	} else{
		SMSD_Log(DEBUG_NOTICE, Config, "Connected to driver %s", driver_name);
	}


	return ERR_NONE;
}
Exemplo n.º 19
0
Arquivo: sql.c Projeto: joltcan/gammu
static GSM_Error SMSDSQL_InitAfterConnect(GSM_SMSDConfig * Config)
{
	SQL_result res;
	struct GSM_SMSDdbobj *db = Config->db;
	SQL_Var vars[3] = {{SQL_TYPE_STRING, {NULL}}, {SQL_TYPE_STRING, {NULL}}, {SQL_TYPE_NONE, {NULL}}};

	if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_DELETE_PHONE], NULL, NULL, &res) != SQL_OK) {
		SMSD_Log(DEBUG_INFO, Config, "Error deleting from database (%s)", __FUNCTION__);
		return ERR_UNKNOWN;
	}
	db->FreeResult(Config, &res);

	SMSD_Log(DEBUG_INFO, Config, "Inserting phone info");
	vars[0].v.s = Config->enable_send ? "yes" : "no";
	vars[1].v.s = Config->enable_receive ? "yes" : "no";

	if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_INSERT_PHONE], NULL, vars, &res) != SQL_OK) {
		SMSD_Log(DEBUG_INFO, Config, "Error inserting into database (%s)", __FUNCTION__);
		return ERR_UNKNOWN;
	}
	db->FreeResult(Config, &res);

	return ERR_NONE;
}
Exemplo n.º 20
0
Arquivo: mysql.c Projeto: gammu/gammu
/* quote strings */
char * SMSDMySQL_QuoteString(GSM_SMSDConfig * Config, const char *string)
{
	char *buff;
	int len = strlen(string);
	buff = malloc(len*2+3);

	if (buff == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "String allocation for escaping failed!");
		return NULL;
	}

	buff[0] = '\'';
	buff[1] = '\0';
	mysql_real_escape_string(Config->conn.my, buff+1, string, len);
	strcat(buff, "'");
	return buff;
}
Exemplo n.º 21
0
Arquivo: sql.c Projeto: joltcan/gammu
static GSM_Error SMSDSQL_CheckTable(GSM_SMSDConfig * Config, const char *table)
{
	SQL_result res;
	char buffer[200];
	SQL_Error error;
	struct GSM_SMSDdbobj *db = Config->db;
	const char *escape_char;

	escape_char = SMSDSQL_EscapeChar(Config);

	sprintf(buffer, "SELECT %s %sID%s FROM %s %s", SMSDSQL_TopClause(Config, "1"), escape_char, escape_char, table, SMSDSQL_LimitClause(Config, "1"));
	error = SMSDSQL_Query(Config, buffer, &res);
	if (error != SQL_OK) {
		SMSD_Log(DEBUG_ERROR, Config, "Table %s not found, disconnecting!", table);
		db->Free(Config);
		return ERR_UNKNOWN;
	}
	db->FreeResult(Config, &res);
	return ERR_NONE;
}
Exemplo n.º 22
0
Arquivo: sql.c Projeto: joltcan/gammu
static GSM_Error SMSDSQL_RefreshSendStatus(GSM_SMSDConfig * Config, char *ID)
{
	SQL_result res;
	struct GSM_SMSDdbobj *db = Config->db;
	SQL_Var vars[2] = {
		{SQL_TYPE_STRING, {ID}},
		{SQL_TYPE_NONE, {NULL}}};

	if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_REFRESH_SEND_STATUS], NULL, vars, &res) != SQL_OK) {
		SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__);
		return ERR_UNKNOWN;
	}

	if (db->AffectedRows(Config, &res) == 0) {
		db->FreeResult(Config, &res);
		return ERR_UNKNOWN;
	}

	db->FreeResult(Config, &res);
	return ERR_NONE;
}
Exemplo n.º 23
0
static GSM_Error SMSDSQL_UpdateRetries(GSM_SMSDConfig * Config, char *ID)
{
	SQL_result res;
	struct GSM_SMSDdbobj *db = Config->db;
	SQL_Var vars[3] = {
		{SQL_TYPE_STRING, {ID}},
		{SQL_TYPE_INT, {NULL}},
		{SQL_TYPE_NONE, {NULL}}};
	vars[1].v.i = Config->retries;

	if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_UPDATE_RETRIES], NULL, vars, &res) != SQL_OK) {
		SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__);
		return ERR_UNKNOWN;
	}

	if (db->AffectedRows(Config, &res) == 0) {
		db->FreeResult(Config, &res);
		return ERR_UNKNOWN;
	}

	db->FreeResult(Config, &res);
	return ERR_NONE;
}
Exemplo n.º 24
0
Arquivo: sql.c Projeto: joltcan/gammu
/* Find one multi SMS to sending and return it (or return ERR_EMPTY)
 * There is also set ID for SMS
 */
static GSM_Error SMSDSQL_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char *ID)
{
	SQL_result res;
	struct GSM_SMSDdbobj *db = Config->db;
	int i;
	time_t timestamp;
	const char *coding;
	const char *text;
	size_t text_len;
	const char *text_decoded;
	const char *destination;
	const char *udh;
	const char *q;
	size_t udh_len;
	SQL_Var vars[3];

	vars[0].type = SQL_TYPE_INT;
	vars[0].v.i = 1;
	vars[1].type = SQL_TYPE_NONE;

	while (TRUE) {
		if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_SMS_ID], NULL, vars, &res) != SQL_OK) {
			SMSD_Log(DEBUG_INFO, Config, "Error reading from database (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}

		if (db->NextRow(Config, &res) != 1) {
			db->FreeResult(Config, &res);
			return ERR_EMPTY;
		}

		sprintf(ID, "%ld", (long)db->GetNumber(Config, &res, 0));
		timestamp = db->GetDate(Config, &res, 1);

		db->FreeResult(Config, &res);

		if (timestamp == -1) {
			SMSD_Log(DEBUG_INFO, Config, "Invalid date for InsertIntoDB.");
			return ERR_UNKNOWN;
		}

		SMSDSQL_Time2String(Config, timestamp, Config->DT, sizeof(Config->DT));
		if (SMSDSQL_RefreshSendStatus(Config, ID) == ERR_NONE) {
			break;
		}
	}

	sms->Number = 0;
	for (i = 0; i < GSM_MAX_MULTI_SMS; i++) {
		GSM_SetDefaultSMSData(&sms->SMS[i]);
		sms->SMS[i].SMSC.Number[0] = 0;
		sms->SMS[i].SMSC.Number[1] = 0;
	}

	for (i = 1; i < GSM_MAX_MULTI_SMS + 1; i++) {
		vars[0].type = SQL_TYPE_STRING;
		vars[0].v.s = ID;
		vars[1].type = SQL_TYPE_INT;
		vars[1].v.i = i;
		vars[2].type = SQL_TYPE_NONE;
		if (i == 1) {
			q = Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_BODY];
		} else {
			q = Config->SMSDSQL_queries[SQL_QUERY_FIND_OUTBOX_MULTIPART];
		}
		if (SMSDSQL_NamedQuery(Config, q, NULL, vars, &res) != SQL_OK) {
			SMSD_Log(DEBUG_ERROR, Config, "Error reading from database (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}

		if (db->NextRow(Config, &res) != 1) {
			db->FreeResult(Config, &res);
			return ERR_NONE;
		}

		coding = db->GetString(Config, &res, 1);
		text = db->GetString(Config, &res, 0);
		if (text == NULL) {
			text_len = 0;
		} else {
			text_len = strlen(text);
		}
		text_decoded = db->GetString(Config, &res, 4);
		udh = db->GetString(Config, &res, 2);
		if (udh == NULL) {
			udh_len = 0;
		} else {
			udh_len = strlen(udh);
		}

		sms->SMS[sms->Number].Coding = GSM_StringToSMSCoding(coding);
		if (sms->SMS[sms->Number].Coding == 0) {
			if (text == NULL || text_len == 0) {
				SMSD_Log(DEBUG_NOTICE, Config, "Assuming default coding for text message");
				sms->SMS[sms->Number].Coding = SMS_Coding_Default_No_Compression;
			} else {
				SMSD_Log(DEBUG_NOTICE, Config, "Assuming 8bit coding for binary message");
				sms->SMS[sms->Number].Coding = SMS_Coding_8bit;
			}
		}

		if (text == NULL || text_len == 0) {
			if (text_decoded == NULL) {
				SMSD_Log(DEBUG_ERROR, Config, "Message without text!");
				return ERR_UNKNOWN;
			} else {
				SMSD_Log(DEBUG_NOTICE, Config, "Message: %s", text_decoded);
				DecodeUTF8(sms->SMS[sms->Number].Text, text_decoded, strlen(text_decoded));
			}
		} else {
			switch (sms->SMS[sms->Number].Coding) {
				case SMS_Coding_Unicode_No_Compression:

				case SMS_Coding_Default_No_Compression:
					DecodeHexUnicode(sms->SMS[sms->Number].Text, text, text_len);
					break;

				case SMS_Coding_8bit:
					DecodeHexBin(sms->SMS[sms->Number].Text, text, text_len);
					sms->SMS[sms->Number].Length = text_len / 2;
					break;

				default:
					break;
			}
		}

		if (i == 1) {
			destination = db->GetString(Config, &res, 6);
			if (destination == NULL) {
				SMSD_Log(DEBUG_ERROR, Config, "Message without recipient!");
				return ERR_UNKNOWN;
			}
			DecodeUTF8(sms->SMS[sms->Number].Number, destination, strlen(destination));
		} else {
			CopyUnicodeString(sms->SMS[sms->Number].Number, sms->SMS[0].Number);
		}

		sms->SMS[sms->Number].UDH.Type = UDH_NoUDH;
		if (udh != NULL && udh_len != 0) {
			sms->SMS[sms->Number].UDH.Type = UDH_UserUDH;
			sms->SMS[sms->Number].UDH.Length = udh_len / 2;
			DecodeHexBin(sms->SMS[sms->Number].UDH.Text, udh, udh_len);
		}

		sms->SMS[sms->Number].Class = db->GetNumber(Config, &res, 3);
		sms->SMS[sms->Number].PDU = SMS_Submit;
		sms->Number++;

		if (i == 1) {
			strcpy(Config->CreatorID, db->GetString(Config, &res, 10));
			Config->relativevalidity = db->GetNumber(Config, &res, 8);

			Config->currdeliveryreport = db->GetBool(Config, &res, 9);

			/* Is this a multipart message? */
			if (!db->GetBool(Config, &res, 7)) {
				db->FreeResult(Config, &res);
				break;
			}

		}
		db->FreeResult(Config, &res);
	}

	return ERR_NONE;
}
Exemplo n.º 25
0
Arquivo: sql.c Projeto: joltcan/gammu
/* Save SMS from phone (called Inbox sms - it's in phone Inbox) somewhere */
static GSM_Error SMSDSQL_SaveInboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char **Locations)
{
	SQL_result res, res2;
	SQL_Var vars[3];
	struct GSM_SMSDdbobj *db = Config->db;
	const char *q, *status;

	char smstext[3 * GSM_MAX_SMS_LENGTH + 1];
	char destinationnumber[3 * GSM_MAX_NUMBER_LENGTH + 1];
	char smsc_message[3 * GSM_MAX_NUMBER_LENGTH + 1];
	int i;
	time_t t_time1, t_time2;
	gboolean found;
	long diff;
	unsigned long long new_id;
	size_t locations_size = 0, locations_pos = 0;
	const char *state, *smsc;

	*Locations = NULL;

	for (i = 0; i < sms->Number; i++) {
		EncodeUTF8(destinationnumber, sms->SMS[i].Number);
		EncodeUTF8(smsc_message, sms->SMS[i].SMSC.Number);
		if (sms->SMS[i].PDU == SMS_Status_Report) {
			EncodeUTF8(smstext, sms->SMS[i].Text);
			SMSD_Log(DEBUG_INFO, Config, "Delivery report: %s to %s", smstext, destinationnumber);

			if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_SELECT], &sms->SMS[i], NULL, &res) != SQL_OK) {
				SMSD_Log(DEBUG_INFO, Config, "Error reading from database (%s)", __FUNCTION__);
				return ERR_UNKNOWN;
			}

			found = FALSE;
			while (db->NextRow(Config, &res)) {
				smsc = db->GetString(Config, &res, 4);
				state = db->GetString(Config, &res, 1);
				SMSD_Log(DEBUG_NOTICE, Config, "Checking for delivery report, SMSC=%s, state=%s", smsc, state);

				if (strcmp(smsc, smsc_message) != 0) {
					if (Config->skipsmscnumber[0] == 0 || strcmp(Config->skipsmscnumber, smsc)) {
						continue;
					}
				}

				if (strcmp(state, "SendingOK") == 0 || strcmp(state, "DeliveryPending") == 0) {
					t_time1 = db->GetDate(Config, &res, 2);
					if (t_time1 < 0) {
						SMSD_Log(DEBUG_ERROR, Config, "Invalid SendingDateTime -1 for SMS TPMR=%i", sms->SMS[i].MessageReference);
						return ERR_UNKNOWN;
					}
					t_time2 = Fill_Time_T(sms->SMS[i].DateTime);
					diff = t_time2 - t_time1;

					if (diff > -Config->deliveryreportdelay && diff < Config->deliveryreportdelay) {
						found = TRUE;
						break;
					} else {
						SMSD_Log(DEBUG_NOTICE, Config,
							 "Delivery report would match, but time delta is too big (%ld), consider increasing DeliveryReportDelay", diff);
					}
				}
			}

			if (found) {
				if (!strcmp(smstext, "Delivered")) {
					q = Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_UPDATE_DELIVERED];
				} else {
					q = Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_UPDATE];
				}

				if (!strcmp(smstext, "Delivered")) {
					status = "DeliveryOK";
				} else if (!strcmp(smstext, "Failed")) {
					status = "DeliveryFailed";
				} else if (!strcmp(smstext, "Pending")) {
					status = "DeliveryPending";
				} else if (!strcmp(smstext, "Unknown")) {
					status = "DeliveryUnknown";
				} else {
					status = "";
				}

				vars[0].type = SQL_TYPE_STRING;
				vars[0].v.s = status;			/* Status */
				vars[1].type = SQL_TYPE_INT;
				vars[1].v.i = (long)db->GetNumber(Config, &res, 0); /* ID */
				vars[2].type = SQL_TYPE_NONE;

				if (SMSDSQL_NamedQuery(Config, q, &sms->SMS[i], vars, &res2) != SQL_OK) {
					SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__);
					return ERR_UNKNOWN;
				}
				db->FreeResult(Config, &res2);
			}
			db->FreeResult(Config, &res);
			continue;
		}

		if (sms->SMS[i].PDU != SMS_Deliver)
			continue;

		if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_SAVE_INBOX_SMS_INSERT], &sms->SMS[i], NULL, &res) != SQL_OK) {
			SMSD_Log(DEBUG_INFO, Config, "Error writing to database (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}

		new_id = db->SeqID(Config, "inbox_ID_seq");
		if (new_id == 0) {
			SMSD_Log(DEBUG_INFO, Config, "Failed to get inserted row ID (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}
		SMSD_Log(DEBUG_NOTICE, Config, "Inserted message id %lu", (long)new_id);

		db->FreeResult(Config, &res);

		if (new_id != 0) {
			if (locations_pos + 10 >= locations_size) {
				locations_size += 40;
				*Locations = (char *)realloc(*Locations, locations_size);
				assert(*Locations != NULL);
				if (locations_pos == 0) {
					*Locations[0] = 0;
				}
			}
			locations_pos += sprintf((*Locations) + locations_pos, "%lu ", (long)new_id);
		}

		if (SMSDSQL_NamedQuery(Config, Config->SMSDSQL_queries[SQL_QUERY_UPDATE_RECEIVED], &sms->SMS[i], NULL, &res2) != SQL_OK) {
			SMSD_Log(DEBUG_INFO, Config, "Error updating number of received messages (%s)", __FUNCTION__);
			return ERR_UNKNOWN;
		}
		db->FreeResult(Config, &res2);

	}

	return ERR_NONE;
}
Exemplo n.º 26
0
/* Find one multi SMS to sending and return it (or return ERR_EMPTY)
 * There is also set ID for SMS
 * File extension convention:
 * OUTxxxxx.txt : normal text SMS
 * Options appended to the extension applying to this SMS only:
 * d: delivery report requested
 * f: flash SMS
 * b: WAP bookmark as name,URL
 * e.g. OUTG20040620_193810_123_+4512345678_xpq.txtdf
 * is a flash text SMS requesting delivery reports
 */
static GSM_Error SMSDFiles_FindOutboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char *ID)
{
	GSM_MultiPartSMSInfo SMSInfo;
	GSM_WAPBookmark Bookmark;
	char FileName[100], FullName[400];
	unsigned char Buffer[(GSM_MAX_SMS_LENGTH * GSM_MAX_MULTI_SMS + 1) * 2];
	unsigned char Buffer2[(GSM_MAX_SMS_LENGTH * GSM_MAX_MULTI_SMS + 1) * 2];
	FILE *File;
	int i, len, phlen;
	char *pos1, *pos2, *options = NULL;
	gboolean backup = FALSE;
#ifdef GSM_ENABLE_BACKUP
	GSM_SMS_Backup smsbackup;
	GSM_Error error;
#endif
#ifdef WIN32
	struct _finddata_t c_file;
	intptr_t hFile;

	strcpy(FullName, Config->outboxpath);
	strcat(FullName, "OUT*.txt*");
	hFile = _findfirst(FullName, &c_file);
	if (hFile == -1) {
		strcpy(FullName, Config->outboxpath);
		strcat(FullName, "OUT*.smsbackup*");
		hFile = _findfirst(FullName, &c_file);
		backup = TRUE;
	}
	if (hFile == -1) {
		return ERR_EMPTY;
	} else {
		strcpy(FileName, c_file.name);
	}
	_findclose(hFile);
#elif defined(HAVE_DIRBROWSING)
	struct dirent **namelist = NULL;
	int cur_file, num_files;
	char *pos;

	strcpy(FullName, Config->outboxpath);

	FullName[strlen(Config->outboxpath) - 1] = '\0';

	num_files = scandir(FullName, &namelist, 0, alphasort);

	for (cur_file = 0; cur_file < num_files; cur_file++) {
		/* Hidden file or current/parent directory */
		if (namelist[cur_file]->d_name[0] == '.') {
			continue;
		}
		/* We care only about files starting with out */
		if (strncasecmp(namelist[cur_file]->d_name, "out", 3) != 0) {
			continue;
		}
		/* Check extension */
		pos = strrchr(namelist[cur_file]->d_name, '.');
		if (pos == NULL) {
			continue;
		}
		if (strncasecmp(pos, ".txt", 4) == 0) {
			/* We have found text file */
			backup = FALSE;
			break;
		}
		if (strncasecmp(pos, ".smsbackup", 10) == 0) {
			/* We have found a SMS backup file */
			backup = TRUE;
			break;
		}
	}
	/* Remember file name */
	if (cur_file < num_files) {
		strcpy(FileName, namelist[cur_file]->d_name);
	}
	/* Free scandir result */
	for (i = 0; i < num_files; i++) {
		free(namelist[i]);
	}
	free(namelist);
	namelist = NULL;
	/* Did we actually find something? */
	if (cur_file >= num_files) {
		return ERR_EMPTY;
	}
#else
	return ERR_NOTSUPPORTED;
#endif
	strcpy(FullName, Config->outboxpath);
	strcat(FullName, FileName);

	if (backup) {
#ifdef GSM_ENABLE_BACKUP
		/* Remember ID */
		strcpy(ID, FileName);
		/* Load backup */
		GSM_ClearSMSBackup(&smsbackup);
		error = GSM_ReadSMSBackupFile(FullName, &smsbackup);
		if (error != ERR_NONE) {
			return error;
		}
		/* Copy it to our message */
		sms->Number = 0;
		for (i = 0; smsbackup.SMS[i] != NULL; i++) {
			sms->SMS[sms->Number++] = *smsbackup.SMS[i];
		}
		/* Free memory */
		GSM_FreeSMSBackup(&smsbackup);

		/* Set delivery report flag */
		if (sms->SMS[0].PDU == SMS_Status_Report) {
			Config->currdeliveryreport = 1;
		} else {
			Config->currdeliveryreport = -1;
		}

#else
		SMSD_Log(DEBUG_ERROR, Config, "SMS backup loading disabled at compile time!");
		return ERR_DISABLED;

#endif
	} else {
		options = strrchr(FileName, '.') + 4;

		File = fopen(FullName, "rb");
		if (File == NULL) {
			return ERR_CANTOPENFILE;
		}
		len = fread(Buffer, 1, sizeof(Buffer) - 2, File);
		fclose(File);

		if ((len < 2) || (len >= 2 && ((Buffer[0] != 0xFF || Buffer[1] != 0xFE) && (Buffer[0] != 0xFE || Buffer[1] != 0xFF)))) {
			if (len > GSM_MAX_SMS_LENGTH * GSM_MAX_MULTI_SMS)
				len = GSM_MAX_SMS_LENGTH * GSM_MAX_MULTI_SMS;
			EncodeUnicode(Buffer2, Buffer, len);
			len = len * 2;
			memmove(Buffer, Buffer2, len);
			Buffer[len] = 0;
			Buffer[len + 1] = 0;
		} else {
			Buffer[len] = 0;
			Buffer[len + 1] = 0;
			/* Possibly convert byte order */
			ReadUnicodeFile(Buffer2, Buffer);
		}

		GSM_ClearMultiPartSMSInfo(&SMSInfo);
		sms->Number = 0;

		SMSInfo.ReplaceMessage = 0;
		SMSInfo.Entries[0].Buffer = Buffer2;
		SMSInfo.Class = -1;
		SMSInfo.EntriesNum = 1;
		Config->currdeliveryreport = -1;
		if (strchr(options, 'd'))
			Config->currdeliveryreport = 1;
		if (strchr(options, 'f'))
			SMSInfo.Class = 0;	/* flash SMS */

		if (strcasecmp(Config->transmitformat, "unicode") == 0) {
			SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong;
			SMSInfo.UnicodeCoding = TRUE;
		} else if (strcasecmp(Config->transmitformat, "7bit") == 0) {
			SMSInfo.Entries[0].ID = SMS_ConcatenatedTextLong;
			SMSInfo.UnicodeCoding = FALSE;
		} else {
			/* auto */
			SMSInfo.Entries[0].ID = SMS_ConcatenatedAutoTextLong;
		}

		if (strchr(options, 'b')) {	// WAP bookmark as title,URL
			SMSInfo.Entries[0].Buffer = NULL;
			SMSInfo.Entries[0].Bookmark = &Bookmark;
			SMSInfo.Entries[0].ID = SMS_NokiaWAPBookmarkLong;
			SMSInfo.Entries[0].Bookmark->Location = 0;
			pos2 = mywstrstr(Buffer2, "\0,");
			if (pos2 == NULL) {
				pos2 = Buffer2;
			} else {
				*pos2 = '\0';
				pos2++;
				*pos2 = '\0';
				pos2++;	// replace comma by zero
			}

			len = UnicodeLength(Buffer2);
			if (len > 50) {
				len = 50;
			}
			memmove(&SMSInfo.Entries[0].Bookmark->Title, Buffer2, len * 2);
			pos1 = &SMSInfo.Entries[0].Bookmark->Title[0] + len * 2;
			*pos1 = '\0';
			pos1++;
			*pos1 = '\0';

			len = UnicodeLength(pos2);
			if (len > 255) {
				len = 255;
			}
			memmove(&SMSInfo.Entries[0].Bookmark->Address, pos2, len * 2);
			pos1 = &SMSInfo.Entries[0].Bookmark->Address[0] + len * 2;
			*pos1 = '\0';
			pos1++;
			*pos1 = '\0';
		}

		GSM_EncodeMultiPartSMS(GSM_GetDebug(Config->gsm), &SMSInfo, sms);

		strcpy(ID, FileName);
		pos1 = FileName;
		for (i = 1; i <= 3 && pos1 != NULL; i++) {
			pos1 = strchr(++pos1, '_');
		}
		if (pos1 != NULL) {
			/* OUT<priority><date>_<time>_<serialno>_<phone number>_<anything>.txt */
			pos2 = strchr(++pos1, '_');
			if (pos2 != NULL) {
				phlen = strlen(pos1) - strlen(pos2);
			} else {
				/* something wrong */
				return ERR_UNKNOWN;
			}
		} else if (i == 2) {
			/* OUTxxxxxxx.txt or OUTxxxxxxx */
			pos1 = &FileName[3];
			pos2 = strchr(pos1, '.');
			if (pos2 == NULL) {
				phlen = strlen(pos1);
			} else {
				phlen = strlen(pos1) - strlen(pos2);
			}
		} else if (i == 4) {
			/* OUT<priority>_<phone number>_<serialno>.txt */
			pos1 = strchr(FileName, '_');
			pos2 = strchr(++pos1, '_');
			phlen = strlen(pos1) - strlen(pos2);
		} else {
			/* something wrong */
			return ERR_UNKNOWN;
		}

		for (len = 0; len < sms->Number; len++) {
			EncodeUnicode(sms->SMS[len].Number, pos1, phlen);
		}
	}

	if (sms->Number != 0) {
		DecodeUnicode(sms->SMS[0].Number, Buffer);
		if (options != NULL && strchr(options, 'b')) {	// WAP bookmark as title,URL
			SMSD_Log(DEBUG_NOTICE, Config, "Found %i sms to \"%s\" with bookmark \"%s\" cod %i lgt %i udh: t %i l %i dlr: %i fls: %i",
				 sms->Number,
				 Buffer,
				 DecodeUnicodeString(SMSInfo.Entries[0].Bookmark->Address),
				 sms->SMS[0].Coding, sms->SMS[0].Length, sms->SMS[0].UDH.Type, sms->SMS[0].UDH.Length, Config->currdeliveryreport, SMSInfo.Class);
		} else {
			SMSD_Log(DEBUG_NOTICE, Config, "Found %i sms to \"%s\" with text \"%s\" cod %i lgt %i udh: t %i l %i dlr: %i fls: %i",
				 sms->Number,
				 Buffer,
				 DecodeUnicodeString(sms->SMS[0].Text),
				 sms->SMS[0].Coding, sms->SMS[0].Length, sms->SMS[0].UDH.Type, sms->SMS[0].UDH.Length, Config->currdeliveryreport, sms->SMS[0].Class);
		}
	} else {
		SMSD_Log(DEBUG_NOTICE, Config, "error: SMS-count = 0");
	}

	return ERR_NONE;
}
Exemplo n.º 27
0
/* Save SMS from phone (called Inbox sms - it's in phone Inbox) somewhere */
static GSM_Error SMSDFiles_SaveInboxSMS(GSM_MultiSMSMessage * sms, GSM_SMSDConfig * Config, char **Locations)
{
	GSM_Error error = ERR_NONE;
	int i, j;
	unsigned char FileName[100], FullName[400], ext[4], buffer[64], buffer2[400];
	gboolean done;
	FILE *file;
	size_t locations_size = 0, locations_pos = 0;
#ifdef GSM_ENABLE_BACKUP
	GSM_SMS_Backup backup;
#endif
	*Locations = NULL;

	j = 0;
	done = FALSE;
	for (i = 0; i < sms->Number && !done; i++) {
		strcpy(ext, "txt");
		if (sms->SMS[i].Coding == SMS_Coding_8bit)
			strcpy(ext, "bin");
		DecodeUnicode(sms->SMS[i].Number, buffer2);
		/* we loop on yy for the first SMS assuming that if xxxx_yy_00.ext is absent,
		   any xxxx_yy_01,02, must be garbage, that can be overwritten */
		file = NULL;
		do {
			sprintf(FileName,
				"IN%02d%02d%02d_%02d%02d%02d_%02i_%s_%02i.%s",
				sms->SMS[i].DateTime.Year, sms->SMS[i].DateTime.Month, sms->SMS[i].DateTime.Day,
				sms->SMS[i].DateTime.Hour, sms->SMS[i].DateTime.Minute, sms->SMS[i].DateTime.Second, j, buffer2, i, ext);
			strcpy(FullName, Config->inboxpath);
			strcat(FullName, FileName);
			if (file)
				fclose(file);
			file = fopen(FullName, "r");
		} while ((i == 0) && file != NULL && (++j < 100));

		if (file) {
			fclose(file);
			if (i == 0) {
				SMSD_Log(DEBUG_ERROR, Config, "Cannot save %s. No available file names", FileName);
				return ERR_CANTOPENFILE;
			}
		}
		errno = 0;

		if ((sms->SMS[i].PDU == SMS_Status_Report) && strcasecmp(Config->deliveryreport, "log") == 0) {
			strcpy(buffer, DecodeUnicodeString(sms->SMS[i].Number));
			SMSD_Log(DEBUG_NOTICE, Config, "Delivery report: %s to %s, message reference 0x%02x",
				 DecodeUnicodeString(sms->SMS[i].Text), buffer, sms->SMS[i].MessageReference);
		} else {
			if (locations_pos + strlen(FileName) + 2 >= locations_size) {
				locations_size += strlen(FileName) + 30;
				*Locations = (char *)realloc(*Locations, locations_size);
				assert(*Locations != NULL);
				if (locations_pos == 0) {
					*Locations[0] = 0;
				}
			}
			strcat(*Locations, FileName);
			strcat(*Locations, " ");
			locations_pos += strlen(FileName) + 1;

			if (strcasecmp(Config->inboxformat, "detail") == 0) {
#ifndef GSM_ENABLE_BACKUP
				SMSD_Log(DEBUG_ERROR, Config, "Saving in detail format not compiled in!");

#else
				for (j = 0; j < sms->Number; j++) {
					backup.SMS[j] = &sms->SMS[j];
				}
				backup.SMS[sms->Number] = NULL;
				error = GSM_AddSMSBackupFile(FullName, &backup);
				done = TRUE;
#endif
			} else {
				file = fopen(FullName, "wb");
				if (file == NULL) {
					SMSD_LogErrno(Config, "Cannot save file!");
					return ERR_CANTOPENFILE;
				}

				switch (sms->SMS[i].Coding) {
					case SMS_Coding_Unicode_No_Compression:
					case SMS_Coding_Default_No_Compression:
						DecodeUnicode(sms->SMS[i].Text, buffer2);
						if (strcasecmp(Config->inboxformat, "unicode") == 0) {
							buffer[0] = 0xFE;
							buffer[1] = 0xFF;
							chk_fwrite(buffer, 1, 2, file);
							chk_fwrite(sms->SMS[i].Text, 1, strlen(buffer2) * 2, file);
						} else {
							chk_fwrite(buffer2, 1, strlen(buffer2), file);
						}
						break;
					case SMS_Coding_8bit:
						chk_fwrite(sms->SMS[i].Text, 1, (size_t) sms->SMS[i].Length, file);
					default:
						break;
				}
				fclose(file);
			}

			if (error != ERR_NONE) {
				return error;
			}

			SMSD_Log(DEBUG_INFO, Config, "%s %s", (sms->SMS[i].PDU == SMS_Status_Report ? "Delivery report" : "Received"), FileName);
		}
	}
	return ERR_NONE;
fail:
	return ERR_WRITING_FILE;
}
Exemplo n.º 28
0
Arquivo: sql.c Projeto: joltcan/gammu
static SQL_Error SMSDSQL_NamedQuery(GSM_SMSDConfig * Config, const char *sql_query, GSM_SMSMessage *sms,
	const SQL_Var *params, SQL_result * res)
{
	char buff[65536], *ptr, c, static_buff[8192];
	char *buffer2, *end;
	const char *to_print, *q = sql_query;
	int int_to_print;
	int numeric;
	int n, argc = 0;
	struct GSM_SMSDdbobj *db = Config->db;

	if (params != NULL) {
		while (params[argc].type != SQL_TYPE_NONE) argc++;
	}

	ptr = buff;

	do {
		if (*q != '%') {
			*ptr++ = *q;
			continue;
		}
		c = *(++q);
		if( c >= '0' && c <= '9'){
			n = strtoul(q, &end, 10) - 1;
			if (n < argc && n >= 0) {
				switch(params[n].type){
					case SQL_TYPE_INT:
						ptr += sprintf(ptr, "%i", params[n].v.i);
						break;
					case SQL_TYPE_STRING:
						buffer2 = db->QuoteString(Config, params[n].v.s);
						memcpy(ptr, buffer2, strlen(buffer2));
						ptr += strlen(buffer2);
						free(buffer2);
						break;
					default:
						SMSD_Log(DEBUG_ERROR, Config, "SQL: unknown type: %i (application bug) in query: `%s`", params[n].type, sql_query);
						return SQL_BUG;
						break;
				}
			} else {
				SMSD_Log(DEBUG_ERROR, Config, "SQL: wrong number of parameter: %i (max %i) in query: `%s`", n+1, argc, sql_query);
				return SQL_BUG;
			}
			q = end - 1;
			continue;
		}
		numeric = 0;
		to_print = NULL;
		switch (c) {
			case 'I':
				to_print = Config->Status->IMEI;
				break;
			case 'P':
				to_print = Config->PhoneID;
				break;
			case 'N':
				snprintf(static_buff, sizeof(static_buff), "Gammu %s, %s, %s", GAMMU_VERSION, GetOS(), GetCompiler());
				to_print = static_buff;
				break;
			case 'A':
				to_print = Config->CreatorID;
				break;
			default:
				if (sms != NULL) {
					switch (c) {
						case 'R':
							EncodeUTF8(static_buff, sms->Number);
							to_print = static_buff;
							break;
						case 'F':
							EncodeUTF8(static_buff, sms->SMSC.Number);
							to_print = static_buff;
							break;
						case 'u':
							if (sms->UDH.Type != UDH_NoUDH) {
								EncodeHexBin(static_buff, sms->UDH.Text, sms->UDH.Length);
								to_print = static_buff;
							}else{
								to_print = "";
							}
							break;
						case 'x':
							int_to_print =  sms->Class;
							numeric = 1;
							break;
						case 'c':
							to_print = GSM_SMSCodingToString(sms->Coding);
							break;
						case 't':
							int_to_print =  sms->MessageReference;
							numeric = 1;
							break;
						case 'E':
							switch (sms->Coding) {
								case SMS_Coding_Unicode_No_Compression:
								case SMS_Coding_Default_No_Compression:
									EncodeHexUnicode(static_buff, sms->Text, UnicodeLength(sms->Text));
									break;
								case SMS_Coding_8bit:
									EncodeHexBin(static_buff, sms->Text, sms->Length);
									break;
								default:
									*static_buff = '\0';
									break;
							}
							to_print = static_buff;
							break;
						case 'T':
							switch (sms->Coding) {
								case SMS_Coding_Unicode_No_Compression:
								case SMS_Coding_Default_No_Compression:
									EncodeUTF8(static_buff, sms->Text);
									to_print = static_buff;
									break;
								default:
									to_print = "";
									break;
							}
							break;
						case 'V':
							if (sms->SMSC.Validity.Format == SMS_Validity_RelativeFormat) {
								int_to_print = sms->SMSC.Validity.Relative;
							} else {
								int_to_print =  -1;
							}
							numeric = 1;
							break;
						case 'C':
							SMSDSQL_Time2String(Config, Fill_Time_T(sms->SMSCTime), static_buff, sizeof(static_buff));
							to_print = static_buff;
							break;
						case 'd':
							SMSDSQL_Time2String(Config, Fill_Time_T(sms->DateTime), static_buff, sizeof(static_buff));
							to_print = static_buff;
							break;
						case 'e':
							int_to_print = sms->DeliveryStatus;
							numeric = 1;
							break;
						default:
							SMSD_Log(DEBUG_ERROR, Config, "SQL: uexpected char '%c' in query: %s", c, sql_query);
							return SQL_BUG;

					} /* end of switch */
				} else {
					SMSD_Log(DEBUG_ERROR, Config, "Syntax error in query.. uexpected char '%c' in query: %s", c, sql_query);
					return SQL_BUG;
				}
				break;
		} /* end of switch */
		if (numeric) {
			ptr += sprintf(ptr, "%i", int_to_print);
		} else if (to_print != NULL) {
			buffer2 = db->QuoteString(Config, to_print);
			memcpy(ptr, buffer2, strlen(buffer2));
			ptr += strlen(buffer2);
			free(buffer2);
		} else {
			memcpy(ptr, "NULL", 4);
			ptr += 4;
		}
	} while (*(++q) != '\0');
	*ptr = '\0';
	return SMSDSQL_Query(Config, buff, res);

}
Exemplo n.º 29
0
Arquivo: dbi.c Projeto: Bradan/gammu
/* Connects to database */
static GSM_Error SMSDDBI_Connect(GSM_SMSDConfig * Config)
{
	int rc;
	struct GSM_SMSDdbobj *db = Config->db;

	rc = dbi_initialize(Config->driverspath);

	if (rc == 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI did not find any drivers, try using DriversPath option");
		dbi_shutdown();
		return ERR_DB_DRIVER;
	} else if (rc < 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to initialize!");
		return ERR_DB_DRIVER;
	}

	Config->conn.dbi = dbi_conn_new(Config->driver);
	if (Config->conn.dbi == NULL) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to init %s driver!", Config->driver);
		dbi_shutdown();
		return ERR_DB_DRIVER;
	} else {
		SMSD_Log(DEBUG_SQL, Config, "Using DBI driver '%s'", dbi_driver_get_name(dbi_conn_get_driver(Config->conn.dbi)));
	}

	dbi_conn_error_handler(Config->conn.dbi, SMSDDBI_Callback, Config);

	if (dbi_conn_set_option(Config->conn.dbi, "sqlite_dbdir", Config->dbdir) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set sqlite_dbdir!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}
	if (dbi_conn_set_option(Config->conn.dbi, "sqlite3_dbdir", Config->dbdir) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set sqlite3_dbdir!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}
	if (dbi_conn_set_option(Config->conn.dbi, "host", Config->host) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set host!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}
	if (dbi_conn_set_option(Config->conn.dbi, "username", Config->user) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set username!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}
	if (dbi_conn_set_option(Config->conn.dbi, "password", Config->password) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set password!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}
	if (dbi_conn_set_option(Config->conn.dbi, "dbname", Config->database) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set dbname!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}
	if (dbi_conn_set_option(Config->conn.dbi, "encoding", "UTF-8") != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to set encoding!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONFIG;
	}

	if (dbi_conn_connect(Config->conn.dbi) != 0) {
		SMSD_Log(DEBUG_ERROR, Config, "DBI failed to connect!");
		SMSDDBI_Free(Config);
		return ERR_DB_CONNECT;
	}
	Config->db = db;
	return ERR_NONE;
}