diff options
-rw-r--r-- | blasms.c | 147 |
1 files changed, 144 insertions, 3 deletions
@@ -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); } |