summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blasms.c147
1 files changed, 144 insertions, 3 deletions
diff --git a/blasms.c b/blasms.c
index c8127a0..0687c32 100644
--- a/blasms.c
+++ b/blasms.c
@@ -21,8 +21,10 @@
#include <stdlib.h>
#include <string.h>
-/* Remove trailing \n */
+/* Remove trailing \n from a string */
void remtrailn(char* line) {
+ /* If the last character is a \n, change it into the null
+ character (i.e. end of string). */
if (line[strlen(line) - 1] == '\n') {
line[strlen(line) - 1] = '\0';
}
@@ -33,10 +35,15 @@ void replacestr(char* source, int i, int n, char* str) {
/* Temporary string for building */
char strtmp[1000];
+ /* Copy source string into temporary string */
strcpy(strtmp, source);
+ /* Copy the first i characters back into the source string */
strxfrm(source, strtmp, i);
source[i] = '\0';
+ /* Copy the string to be inserted into the source string */
strcat(source, str);
+ /* Copy the remainder of the temporary string into the source,
+ string, skipping over n characters. */
strcat(source, strtmp + i + n);
}
@@ -44,6 +51,8 @@ void replacestr(char* source, int i, int n, char* str) {
void strtolower(char* destination, char* source) {
int i;
+ /* Loop through each character, converting it into
+ lowercase. */
for (i = 0; i < strlen(source) + 1; i++) {
destination[i] = tolower(source[i]);
}
@@ -51,11 +60,16 @@ void strtolower(char* destination, char* source) {
/* Set a sender's name as part of their number */
void setname(char* telnum) {
+ /* File pointer */
FILE *fp;
+ /* String to read each line of file into */
char line[1024];
+ /* Pointer to store character location searches in */
char *strchrp;
+ /* For keeping track of where we are */
int offset = 0;
+ /* Attempt to open the file */
fp = fopen("phonebook.conf", "r");
if (fp == NULL) {
@@ -63,17 +77,27 @@ void setname(char* telnum) {
return;
}
+ /* Loop through each line of the file */
while (fgets(line, 1024, fp) != NULL) {
+ /* Remove trailing newline */
remtrailn(line);
+ /* Attempt to find the end of the first word */
if ((strchrp = strchr(line + offset, ' ')) != NULL) {
+ /* Convert position of end of first word into an int */
offset = strchrp - line;
+ /* Check if the first word is the same as the given telnum */
if ((strlen(telnum) == offset) && !strncmp(telnum, line, offset)) {
+ /* Find the second word (i.e. the name) */
if ((strchrp = strchr(line + offset + 1, ' ')) != NULL) {
line[strchrp - line] = '\0';
}
+ /* Add " (" to the given telnum */
strcat(telnum, " (");
+ /* Add the found name to the given telnum */
strcat(telnum, line + offset + 1);
+ /* Add ")" to the given telnum */
strcat(telnum, ")");
+ /* Leave this procedure */
return;
}
}
@@ -82,14 +106,23 @@ void setname(char* telnum) {
/* Set a sender's number as part of their name */
void settelnum(char* telnum, char* sms, int *offsetptr) {
+ /* File pointer */
FILE *fp;
+ /* String to read each line of file into */
char line[1024];
+ /* Name to lookup */
char name[1000];
+ /* Current name in phonebook.conf */
char curname[1000];
+ /* Pointer to store character location searches in */
char *strchrp;
+ /* Keep track of where we are, starting from the
+ current point in the calling function. */
int offset = *offsetptr;
+ /* Some loop iteration variables */
int i, j;
+ /* Attempt to open the phonebook */
fp = fopen("phonebook.conf", "r");
if (fp == NULL) {
@@ -97,40 +130,68 @@ void settelnum(char* telnum, char* sms, int *offsetptr) {
return;
}
+ /* Set entire given SMS as the target name for now */
strcpy(name, sms + offset + 1);
+ /* Trim the target name to just the first word of the SMS */
if ((strchrp = strchr(name, ' ')) != NULL) {
offset = strchrp - name;
name[offset] = '\0';
}
+ /* If the name is a wildcard, set it as the telnum
+ for the calling function and leave this function. */
if (!strcmp(name, "*")) {
strcpy(telnum, name);
+ /* Advance the offset to go past this wildcard,
+ for the calling function. */
*offsetptr = *offsetptr + 2;
return;
}
+ /* Convert the name to lowercase for easier comparison */
strtolower(name, name);
+ /* Loop through each line of the file to find a matching name */
while (fgets(line, 1024, fp) != NULL) {
+ /* Remove trailing newline */
remtrailn(line);
+ /* Convert the line to lowercase for easier comparison */
strtolower(line, line);
+ /* Find the end of the first word (i.e. the number which
+ we don't want for now. */
for (i = 0; i < strlen(line); i++) {
if (line[i] == ' ') {
break;
}
}
+ /* Move past the first space */
offset = i + 1;
+ /* Loop through each character in the line, skipping the first
+ word (the number). */
for (i = 0, j = 0; i < strlen(line + offset - 1); i++, j++) {
+ /* If this isn't the end of the word or line, build a name
+ for comparison. */
if (line[i + offset] != ' ' && line[i + offset] != '\0') {
curname[j] = line[i + offset];
+ /* Otherwise, the word or line ended, so check for a match. */
} else {
+ /* Terminate the current name string */
curname[j] = '\0';
+ /* Check to see if the names are a match... */
if (!strcmp(name, curname)) {
+ /* If they match, copy the number from the
+ line into telnum */
strncpy(telnum, line, offset - 1);
+ /* Terminate the string */
telnum[offset - 1] = '\0';
+ /* Advance the offset paste the name for the
+ calling function */
*offsetptr = *offsetptr + strlen(name) + 1;
return;
+ /* ...if they aren't a match, start building a new
+ name from this line (as it might have multiple
+ names for the current number). */
} else {
j = -1;
}
@@ -138,12 +199,14 @@ void settelnum(char* telnum, char* sms, int *offsetptr) {
}
}
+ /* If the name wasn't found, then we don't want to send an SMS,
+ so exit the program. */
printf("Error: %s not found in phonebook.conf.\n", name);
exit(1);
}
int main(int argc, char *argv[]) {
- /* Telephone number (may contain name)*/
+ /* Telephone number (may contain name) */
char telnum[100];
/* Unmodified telephone number length */
int telnumlen;
@@ -172,11 +235,17 @@ int main(int argc, char *argv[]) {
/* Command match / telnum set */
short int match = 0;
+ /* Stores the positions in systemcmd of wildcards,
+ for if multiple phonebook looks are to be done. */
struct {
+ /* Each individual position */
int pos;
} wildcard[1000];
+ /* Number of wildcards (i.e. number of wildcard structs used) */
int wildcards = 0;
+ /* Print some usage information if --help was used, or if exactly
+ two arguments weren't given. */
if (argc != 3 || !strcmp(argv[argc - 1], "--help")) {
fprintf(stderr, "Usage: %s sender-number send-date\n"
"\n"
@@ -217,45 +286,62 @@ int main(int argc, char *argv[]) {
return 1;
}
+ /* Copy first argument into telnum, so it can be manipulated */
strcpy(telnum, argv[1]);
+ /* Print the arguments (usually number/date) */
printf("Phone number: %s\n", telnum);
printf("Date : %s\n", argv[2]);
+ /* Get the actual SMS content from standard input */
fgets(sms, 500, stdin);
+ /* Make sure we got something */
if (sms != NULL) {
+ /* Remove trailing newline */
remtrailn(sms);
printf("Contents : %s\n", sms);
}
+ /* Open configuration file */
fp = fopen("blasms.conf", "r");
+ /* Make sure file opened OK */
if (fp == NULL) {
printf("Error opening blasms.conf.\n");
return 1;
}
+ /* Read each line from the file */
while (fgets(line, 1024, fp) != NULL) {
+ /* Remove traliing newline */
remtrailn(line);
+ /* Try to find the end of the first word (i.e. the first space) */
if ((strchrp = strchr(line, ' ')) != NULL) {
+ /* Position = address of space - address of start of line */
offset = strchrp - line;
if (offset > 10) {
printf("Error, command longer than 10 characters in blasms.conf.\n");
return 1;
}
+ /* Copy that first word into configcmd */
strxfrm(configcmd, line, offset);
configcmd[offset] = '\0';
+ /* If the command was "default", set it as the default
+ command and move to next line in file. */
if (!strcmp(configcmd, "default")) {
strcpy(defaultcmd, line + offset + 1);
continue;
}
- /* If the SMS command doesn't end here, continue */
+ /* If the SMS command doesn't end here, continue. (i.e. it
+ definitely doesn't match the config file command. */
if (sms[offset] != ' ') {
continue;
}
+ /* If it does end here, copy it to smscommand */
strxfrm(smscommand, sms, offset);
smscommand[offset] = '\0';
+ /* If the commands are the same, stop reading the file */
if (!strcmp(smscommand, configcmd)) {
match = 1;
break;
@@ -263,73 +349,113 @@ int main(int argc, char *argv[]) {
}
}
+ /* match was set if a command was found, so set the systemcmd
+ to be the remainder of the current config file line */
if (match) {
strcpy(systemcmd, line + offset + 1);
+ /* If not, use the defaultcmd as set above. */
} else {
strcpy(systemcmd, defaultcmd);
offset = -1;
}
+ /* Reset match to 0 as we use it again */
match = 0;
+ /* Go through each character of systemcmd, looking for
+ recognised macros */
for (i = 0; i < strlen(systemcmd); i++) {
+ /* If a % is found, we might be about to find a macro. */
if (systemcmd[i] == '%') {
+ /* Check the next character for recognised macros */
switch (systemcmd[i+1]) {
+ /* Sender number with name lookup */
case 'N':
+ /* Attempt to look up number to find a name */
setname(telnum);
+ /* Insert number (or number + name) into systemcmd */
replacestr(systemcmd, i, 2, telnum);
break;
+ /* Sender number only */
case 'n':
+ /* Insert number into systemcmd */
replacestr(systemcmd, i, 2, telnum);
break;
+ /* Date */
case 'd':
+ /* Insert date into systemcmd */
replacestr(systemcmd, i, 2, argv[2]);
break;
+ /* SMS content, minus the initial command (if any) */
case 's':
+ /* Insert SMS content into systemcmd */
replacestr(systemcmd, i, 2, sms + offset + 1);
break;
+ /* Interpret second word of SMS as a name to be looked up */
case 'P':
+ /* If name hasn't already been found, try to find it */
if (!match) {
settelnum(telnum, sms, &offset);
+ /* If found, no need to try again. */
match = 1;
}
+ /* If telnum was a wildcard, keep track of its position. */
if (!strcmp(telnum, "*")) {
wildcard[wildcards].pos = i;
wildcards++;
}
+ /* Insert telnum into systemcmd */
replacestr(systemcmd, i, 2, telnum);
break;
+ /* Intepret the second word (i.e. after the command) of the SMS
+ as a filename, attempt to open the file pending/filename, treating
+ the first word of it as a number, attempting to look up its name,
+ and insert a colon between it and the rest of the file. */
case 'M':
+ /* Build the path */
strcpy(telnum, "pending/");
strcat(telnum, sms + offset + 1);
+ /* Open the file */
fp = fopen(telnum, "r");
+ /* If the file didn't open, abort this macro. */
if (fp == NULL) {
printf("Error opening message file.\n");
break;
}
+ /* If the first line can't be read, abort this macro. */
if (fgets(line, 1024, fp) == NULL) {
printf("Error reading message file.\n");
break;
}
+ /* Close the file after reading the first line */
fclose(fp);
+ /* Attempt to find the end of the first word */
if ((strchrp = strchr(line + offset, ' ')) != NULL) {
+ /* Remove trailing newline */
remtrailn(line);
+ /* Copy the first word into telnum */
strncpy(telnum, line, strchrp - line);
telnum[strchrp - line] = '\0';
+ /* Set the length of the unmodified number */
telnumlen = strlen(telnum);
+ /* Attempt to look up the number */
setname(telnum);
+ /* If a first word couldn't be determined, abort this macro. */
} else {
printf("Error, malformed message file.\n");
break;
}
+ /* Insert the number (or number + name) into systemcmd */
replacestr(systemcmd, i, 2, telnum);
+ /* Insert a colon */
replacestr(systemcmd, i + strlen(telnum), 0, ":");
+ /* Insert the remainder of the file */
replacestr(systemcmd, i + strlen(telnum) + 1, 0, line + telnumlen);
break;
@@ -337,28 +463,43 @@ int main(int argc, char *argv[]) {
}
}
+ /* Execute a single command, or multiple command, depending on
+ whether the systemcmd contained wildcards. */
if (wildcards) {
+ /* Try to open the phonebook to look up each number to send to */
fp = fopen("phonebook.conf", "r");
+ /* Exit if the file couldn't be opened */
if (fp == NULL) {
printf("Error opening phonebook.conf.\n");
return 1;
}
+ /* Read each line in the file */
while (fgets(line, 1024, fp) != NULL) {
+ /* Attempt to find the first word (hopefully a number) */
if ((strchrp = strchr(line, ' ')) != NULL) {
+ /* Set initial offset in systemcmd (1, as in a single *) */
offset = 1;
+ /* Copy systemcmd into wildcardcmd for manipulation */
strcpy(wildcardcmd, systemcmd);
line[strchrp - line] = '\0';
+ /* Loop through each wildcard that we tracked earlier */
for (i = 0; i < wildcards; i++) {
+ /* Insert the first word of the phonebook (hopefully a number) into
+ wildcardcmd at each wildcard position. Adjust the wildcard position
+ each time to take into account the length of the previous inserted
+ number. */
replacestr(wildcardcmd, wildcard[i].pos + (int)strlen(line) * i - i, 1, line);
}
printf("Executing: %s\n", wildcardcmd);
+ /* Execute the command */
system(wildcardcmd);
}
}
} else {
printf("Executing: %s\n", systemcmd);
+ /* Execute command */
system(systemcmd);
}