📄 smsd.c
字号:
/*SMS Server Tools 3Copyright (C) Keijo Kasvihttp://smstools3.kekekasvi.com/Based on SMS Server Tools 2 from Stefan Fringshttp://www.meinemullemaus.de/This program is free software unless you got it under another license directlyfrom the author. You can redistribute it and/or modify it under the terms ofthe 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 <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <syslog.h>#include <signal.h>#include <time.h>#include <ctype.h>#ifndef NOSTATS#include <mm.h>#endif#include <fcntl.h>#include <unistd.h>#include <pwd.h>#include <grp.h>#include <stdarg.h>#include "extras.h"#include "locking.h"#include "smsd_cfg.h"#include "stats.h"#include "version.h"#include "blacklist.h"#include "whitelist.h"#include "logging.h"#include "alarm.h"#include "charset.h"#include "cfgfile.h"#include "pdu.h"#include "modeminit.h"int logfilehandle; // handle of log file.int concatenated_id=0; // id number for concatenated messages.// This indicates that the PDU was read from file, not from SIM.#define PDUFROMFILE 22222int break_workless_delay; // To break the delay when SIGCONT is received.int workless_delay;const char *HDR_To = "To:"; // Msg file input.char HDR_To2[SIZE_HEADER] = {};const char *HDR_From = "From:"; // Msg file input: informative, incoming message: senders address.char HDR_From2[SIZE_HEADER] = {};const char *HDR_Flash = "Flash:"; // Msg file input.char HDR_Flash2[SIZE_HEADER] = {};const char *HDR_Provider = "Provider:"; // Msg file input.char HDR_Provider2[SIZE_HEADER] = {};const char *HDR_Queue = "Queue:"; // Msg file input.char HDR_Queue2[SIZE_HEADER] = {};const char *HDR_Binary = "Binary:"; // Msg file input (sets alphabet to 1 or 0).char HDR_Binary2[SIZE_HEADER] = {};const char *HDR_Report = "Report:"; // Msg file input. Incoming message: report was asked yes/no.char HDR_Report2[SIZE_HEADER] = {};const char *HDR_Autosplit = "Autosplit:"; // Msg file input.char HDR_Autosplit2[SIZE_HEADER] = {};const char *HDR_Validity = "Validity:"; // Msg file input.char HDR_Validity2[SIZE_HEADER] = {};const char *HDR_Voicecall = "Voicecall:"; // Msg file input.char HDR_Voicecall2[SIZE_HEADER] = {};const char *HDR_Replace = "Replace:"; // Msg file input. Incoming message: exists with code if replacechar HDR_Replace2[SIZE_HEADER] = {}; // code was defined.const char *HDR_Alphabet = "Alphabet:"; // Msg file input. Incoming message.char HDR_Alphabet2[SIZE_HEADER] = {};const char *HDR_Include = "Include:"; // Msg file input.char HDR_Include2[SIZE_HEADER] = {};const char *HDR_Macro = "Macro:"; // Msg file input.char HDR_Macro2[SIZE_HEADER] = {};const char *HDR_Hex = "Hex:"; // Msg file input.char HDR_Hex2[SIZE_HEADER] = {};const char *HDR_SMSC = "SMSC:"; // Msg file input: smsc number.char HDR_SMSC2[SIZE_HEADER] = {};const char *HDR_Priority = "Priority:"; // Msg file input.char HDR_Priority2[SIZE_HEADER] = {};const char *HDR_UDHDATA = "UDH-DATA:"; // Msg file input. Incoming message.const char *HDR_UDHDUMP = "UDH-DUMP:"; // Msg file input (for backward compatibility).const char *HDR_UDH = "UDH:"; // Msg file input. Incoming binary message: "yes" / "no".const char *HDR_Sent = "Sent:"; // Outgoing timestamp, incoming: senders date & time (from PDU).char HDR_Sent2[SIZE_HEADER] = {};const char *HDR_Modem = "Modem:"; // Sent message, device name (=modemname).char HDR_Modem2[SIZE_HEADER] = {};const char *HDR_FromTOA = "From_TOA:"; // Incoming message: senders Type Of Address.char HDR_FromTOA2[SIZE_HEADER] = {};const char *HDR_FromSMSC = "From_SMSC:"; // Incoming message: senders SMSCchar HDR_FromSMSC2[SIZE_HEADER] = {};const char *HDR_Name = "Name:"; // Incoming message: name from the modem response (???).char HDR_Name2[SIZE_HEADER] = {};const char *HDR_Received = "Received:"; // Incoming message timestamp.char HDR_Received2[SIZE_HEADER] = {};const char *HDR_Subject = "Subject:"; // Incoming message, modemname.char HDR_Subject2[SIZE_HEADER] = {};const char *HDR_UDHType = "UDH-Type:"; // Incoming message, type(s) of content of UDH if present.char HDR_UDHType2[SIZE_HEADER] = {};const char *HDR_Length = "Length:"; // Incoming message, text/data length. With Unicode: number of Unicodechar HDR_Length2[SIZE_HEADER] = {}; // characters. With GSM/ISO: nr of chars, may differ if stored as UTF-8.const char *HDR_FailReason = "Fail_reason:"; // Failed outgoing message (currently only spooling uses this).char HDR_FailReason2[SIZE_HEADER] = {};const char *HDR_Identity = "IMSI:"; // Incoming / Sent(or failed), exists with code if IMSI requestchar HDR_Identity2[SIZE_HEADER] = {}; // supported.const char *HDR_MessageId = "Message_id:"; // Sent (successfully) message. There is fixed "message id" andchar HDR_MessageId2[SIZE_HEADER] = {}; // "status" titled inside the body of status report.const char *HDR_OriginalFilename = "Original_filename:"; // Stored when moving file from outgoing directory andchar HDR_OriginalFilename2[SIZE_HEADER] = {}; // unique filenames are used in the spooler.const char *HDR_CallType = "Call_type:"; // Incoming message from phonebook.char HDR_CallType2[SIZE_HEADER] = {};const char *HDR_missed = "missed"; // For incoming call type.char HDR_missed2[SIZE_HEADER] = {};const char *HDR_missed_text = "CALL MISSED"; // For incoming call, message body.char HDR_missed_text2[SIZE_HEADER] = {};const char *HDR_Result = "Result:"; // For voice call, result string from a modemchar HDR_Result2[SIZE_HEADER] = {};int read_translation(void){ int result = 0; // Number of problems FILE *fp; char name[32]; char value[PATH_MAX]; int getline_result; char *p; int i; if (*language_file) { if (!(fp = fopen(language_file, "r"))) { fprintf(stderr, "%s\n", tb_sprintf("Cannot read language file %s: %s", language_file, strerror(errno))); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; } else { while ((getline_result = my_getline(fp, name, sizeof(name), value, sizeof(value))) != 0) { if (getline_result == -1) { fprintf(stderr, "%s\n", tb_sprintf("Syntax Error in language file: %s", value)); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; continue; } if (line_is_blank(value)) { fprintf(stderr, "%s\n", tb_sprintf("%s has no value in language file.", name)); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; continue; } if (strlen(value) >= SIZE_HEADER) { fprintf(stderr, "%s\n", tb_sprintf("Too long value for %s in language file: %s", name, value)); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; continue; } if (*value == '-') { while (value[1] && strchr(" \t", value[1])) strcpy(value +1, value +2); if (!strcasecmp(name, HDR_From) || !strcasecmp(name, HDR_Received) || !strcasecmp(name, HDR_missed) || !strcasecmp(name, HDR_missed_text)) { fprintf(stderr, "%s\n", tb_sprintf("In language file, translation for %s cannot start with '-' character", name)); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; continue; } } if (!strcasecmp(name, "incoming")) translate_incoming = yesno(value); else if (!strcasecmp(name, "datetime")) { // Not much can be checked, only if it's completelly wrong... char timestamp[81]; time_t now; time(&now); if (!strchr(value, '%') || strftime(timestamp, sizeof(timestamp), value, localtime(&now)) == 0 || !strcmp(timestamp, value)) { fprintf(stderr, "%s\n", tb_sprintf("In language file, format for datetime is completelly wrong: \"%s\"", value)); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; continue; } else strcpy(datetime_format, value); } else if (!strcasecmp(name, "yes_word")) strcpy(yes_word, value); else if (!strcasecmp(name, "no_word")) strcpy(no_word, value); else if (!strcasecmp(name, "yes_chars") || !strcasecmp(name, "no_chars")) { // Every possible character (combination) is given between apostrophes. // This is because one UTF-8 character can be represented using more than on byte. // There can be more than one definition delimited with a comma. Uppercase and // lowercase is handled by the definition because of UTF-8 and because of // non-US-ASCII character sets. // Example (very easy one): 'K','k' // First remove commas, spaces and double apostrophes: while ((p = strchr(value, ','))) strcpy(p, p +1); while ((p = strchr(value, ' '))) strcpy(p, p +1); while ((p = strstr(value, "''"))) strcpy(p, p +1); // First apostrophe is not needed: if (value[0] == '\'') strcpy(value, value +1); // Ensure that last apostrophe is there: if ((i = strlen(value)) > 0) { if (value[i -1] != '\'') if (i < SIZE_HEADER -1) strcat(value, "'"); } else { fprintf(stderr, "%s\n", tb_sprintf("%s has an incomplete value in language file", name)); writelogfile(LOG_CRIT, process_title, "%s", tb); result++; continue; } // Example (UTF-8): (byte1)(byte2)(byte3)'(byte1)(byte2)' // yesno() is now able to check what was meant with an answer. if (!strcasecmp(name, "yes_chars")) strcpy(yes_chars, value); else strcpy(no_chars, value); } else if (!strcasecmp(name, HDR_To)) strcpy(HDR_To2, value); else if (!strcasecmp(name, HDR_From))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -