gboolean ReadVCALDateTime(const char *Buffer, GSM_DateTime *dt) { time_t timestamp; char year[5]="", month[3]="", day[3]="", hour[3]="", minute[3]="", second[3]=""; memset(dt,0,sizeof(GSM_DateTime)); /* YYYY-MM-DD is invalid, though used */ if (sscanf(Buffer, "%d-%d-%d", &dt->Year, &dt->Month, &dt->Day) == 3) { goto checkdt; } if (strlen(Buffer) < 8) { return FALSE; } strncpy(year, Buffer, 4); strncpy(month, Buffer+4, 2); strncpy(day, Buffer+6, 2); dt->Year = atoi(year); dt->Month = atoi(month); dt->Day = atoi(day); if (Buffer[8] == 'T') { if (strlen(Buffer + 9) < 6) return FALSE; strncpy(hour, Buffer+9, 2); strncpy(minute, Buffer+11, 2); strncpy(second, Buffer+13, 2); dt->Hour = atoi(hour); dt->Minute = atoi(minute); dt->Second = atoi(second); /** * @todo Handle properly timezone information */ if (Buffer[15] == 'Z') dt->Timezone = 0; /* Z = ZULU = GMT */ } checkdt: if (!CheckTime(dt)) { dbgprintf(NULL, "incorrect date %d-%d-%d %d:%d:%d\n",dt->Day,dt->Month,dt->Year,dt->Hour,dt->Minute,dt->Second); return FALSE; } if (dt->Year!=0) { if (!CheckDate(dt)) { dbgprintf(NULL, "incorrect date %d-%d-%d %d:%d:%d\n",dt->Day,dt->Month,dt->Year,dt->Hour,dt->Minute,dt->Second); return FALSE; } } if (dt->Timezone != 0) { timestamp = Fill_Time_T(*dt) + dt->Timezone; Fill_GSM_DateTime(dt, timestamp); } return TRUE; }
void GetTimeDifference(unsigned long diff, GSM_DateTime *DT, gboolean Plus, int multi) { time_t t_time; t_time = Fill_Time_T(*DT); if (Plus) { t_time += diff*multi; } else { t_time -= diff*multi; } Fill_GSM_DateTime(DT, t_time); dbgprintf(NULL, "EndTime: %02i-%02i-%04i %02i:%02i:%02i\n", DT->Day,DT->Month,DT->Year,DT->Hour,DT->Minute,DT->Second); }
time_t SMSDODBC_GetDate(GSM_SMSDConfig * Config, SQL_result *res, unsigned int field) { SQL_TIMESTAMP_STRUCT sqltime; GSM_DateTime DT; SQLRETURN ret; ret = SQLGetData(res->odbc, field + 1, SQL_C_TYPE_TIMESTAMP, &sqltime, 0, NULL); if (!SQL_SUCCEEDED(ret)) { SMSDODBC_LogError(Config, ret, SQL_HANDLE_STMT, res->odbc, "SQLGetData(timestamp) failed"); return -1; } DT.Year = sqltime.year; DT.Month = sqltime.month; DT.Day = sqltime.day; DT.Hour = sqltime.hour; DT.Minute = sqltime.minute; DT.Second = sqltime.second; return Fill_Time_T(DT); }
/* 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; }
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); }
void GSM_DateTimeToTimestamp(GSM_DateTime *Date, char *str) { time_t timet; timet = Fill_Time_T(*Date); sprintf(str, "%ld", (long)timet); }