[edit] since noone has replied to the old code snippet yet, I'm going to replace it... [/edit]
Here's some C code that checks an email inbox for any mail that has a subject line of "Send IP number". It then deletes that email, and sends the current IP number of the machine to a specific email adress.
You can compile this using the command line, like so: "gcc -lc -O3 -o <executable name> <filename>" or you could do as I did, and use ProjectBuilder.
This code should compile and work just fine on any *nix computer. I'm not guaranteeing anything, though - see this disclaimer:
DISCLAIMER: I take no responsibility whatsoever for any result whatsoever from the use, misuse or inability to use the following code or any derivative of the same.
CODE
// A couple of include files...
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
// This function (listed below) tests your POP email account for emails with
// the subject "Send IP email". It deletes that email and sends a return email
// if that subject line is detected.
void test_for_ip_request_mail(void);
#define NUMBER_OF_MINUTES_BETWEEN_CHECKS 15
int main(void)
{
// Enter an infinite loop...
while(1)
{
// ...wait for a couple of minutes...
sleep(NUMBER_OF_MINUTES_BETWEEN_CHECKS*60);
// ...check the inbox...
test_for_ip_request_mail();
// ...repeat.
}
}
// This function (listed below) opens a TCP connection to a server.
// Used here to connect to the POP and SMTP servers.
static long connect_to_server(char *the_adress, long the_port_number);
// This function (listed below) closes a connection.
static void disconnect_from_server(long connection);
// This is the mail server used to send the email
#define SMTP_SERVER_ADRESS "mail.server.com"
// This is what will be in the "from" field
#define SMTP_IDENTITY "myipfinder@inter.net"
// This is what email adress the email will be sent to
#define SMTP_RECIPIENT "clueless@inter.net"
// When finding the IP, this temporary file will be used.
#define PATH_TO_IP_NUMBER_FILE "/tmp/myip"
// This function sends an email to the recipient above with the correct
// IP number...
static void send_ip(void)
{
// reference to the file containing the IP number
FILE *ip_file;
// how long the IP string is
long ip_string_length;
// the IP number itself
char ip_string[32];
// reference to the server connection
long smtp_connection;
// This should be easily recognised - just finding the computer's
// IP number here..
system(
"curl -s [url="http://www.whatismyip.com"]www.whatismyip.com[/url] | "
"grep "Your ip is" | "
"awk '{print $4}' > "
PATH_TO_IP_NUMBER_FILE);
// The IP number was output to a file, so it has to be opened...
ip_file = fopen(PATH_TO_IP_NUMBER_FILE, "r");
if(ip_file == NULL)
return;
// ...it's size figured out...
fseek(ip_file, 0, SEEK_END);
ip_string_length = ftell(ip_file);
fseek(ip_file, 0, SEEK_SET);
// ...the IP number read...
fread(ip_string, ip_string_length, 1, ip_file);
// ...the string terminated...
ip_string[ip_string_length] = ' ';
// ...the file closed...
fclose(ip_file);
// ...and deleted
system("rm -f " PATH_TO_IP_NUMBER_FILE);
// Connect to the SMTP server...
smtp_connection = connect_to_server(SMTP_SERVER_ADRESS, 25);
if(smtp_connection == -1)
return;
// ...and tell it to send an email.
write(smtp_connection, "HELO ", 5);
write(smtp_connection, ip_string, ip_string_length);
write(
smtp_connection,
"MAIL FROM: " SMTP_IDENTITY "n",
12 + strlen(SMTP_IDENTITY));
write(smtp_connection,
"RCPT TO: " SMTP_RECIPIENT "n",
10 + strlen(SMTP_RECIPIENT));
write(smtp_connection, "DATAn", 5);
write(smtp_connection, "Subject: ", 9);
write(smtp_connection, ip_string, ip_string_length);
write(smtp_connection, ".n", 2);
write(smtp_connection, "QUITn", 5);
// We're done sending the email, so we close the connection.
disconnect_from_server(smtp_connection);
}
// This function (listed below) reads all data sent over the connection so
// far.
static void read_all_remaining_data(long connection);
// This is the POP server that has the email account
#define POP_SERVER_ADRESS "my.mail.server.com"
// This is the email account name
#define POP_USER_NAME "myusername"
// This is the password to use to retrieve data from the POP account
#define POP_PASSWORD "mypassword"
void test_for_ip_request_mail(void)
{
// Reference to the connection to the POP server
long pop_connection;
// The reply from the server
char server_reply[256];
// A couple of loop indices
long i,j;
// the message count
long number_of_messages;
// the current message number to retrieve, in text
char message_number[32];
// Open the connection to the server
pop_connection = connect_to_server(POP_SERVER_ADRESS, 110);
if(pop_connection == -1)
return;
// To make the function shorter, this peice of code, which tests for a
// positive result to the last operation, is made into a #define.
// Works like this: Read 1 character. Read anything that's left.
// If the first character is a '-', then the server reported an error.
// Don't handle error - just bail.
#define POP_CHECK_RESULT
while(read(pop_connection, server_reply, 1) == -1)
;
read_all_remaining_data(pop_connection);
if(server_reply[0] == '-')
{
write(pop_connection, "QUITn", 5);
disconnect_from_server(pop_connection);
return;
}
// Check the result of connecting...
POP_CHECK_RESULT
// ...then identify as a valid user...
write(
pop_connection,
"USER " POP_USER_NAME "n",
6 + strlen(POP_USER_NAME));
// ...test that that went ok...
POP_CHECK_RESULT
// ...now it'll want a password...
write(
pop_connection,
"PASS " POP_PASSWORD "n",
6 + strlen(POP_PASSWORD));
// ...test that it was valid...
POP_CHECK_RESULT
// ...check how many emails are in the inbox...
write(
pop_connection,
"STATn",
5);
// ...test for errors...
// (this time is slightly different, since one of the numbers on this
// line is supposed to be read)
while(read(pop_connection, server_reply, 1) == -1)
;
if(server_reply[0] == '-')
{
write(pop_connection, "QUITn", 5);
disconnect_from_server(pop_connection);
return;
}
// ...everything is ok, skip ahead to the number to read...
while(read(pop_connection, server_reply, 3) == -1)
;
server_reply[0] = ' ';
// ...read the number...
for(i = 0;
i == 0 || server_reply[i-1] != ' ';
i++, server_reply[i] = ' ')
{
while(read(pop_connection, &(server_reply[i]), 1) == -1)
;
}
server_reply[i-1] = ' ';
// ...translate it from text to binary...
number_of_messages = atoi(server_reply);
read_all_remaining_data(pop_connection);
// ...go through each message in the mailbox...
for(i = 1; i <= number_of_messages; i++)
{
// ...fetch one message...
write(pop_connection, "RETR ", 5);
sprintf(message_number, "%ld", i);
write(pop_connection, message_number, strlen(message_number));
write(pop_connection, "n", 1);
// ...the message does exist, right?...
while(read(pop_connection, server_reply, 1) == -1)
;
if(server_reply[0] == '+')
{
// ...good. Skip the first line...
do{
while(read(pop_connection, server_reply, 1) == -1)
;
}while(server_reply[0] != 'n');
// ...then, one at a time, ...
do{
// ...read a line...
j = -1;
do{
j++;
while(read(pop_connection, &(server_reply[j]), 1) == -1)
;
}while(server_reply[j] != 'n');
server_reply[j-1] = ' ';
// ...check if it is the correct subject line...
if(strncmp(server_reply, "Subject: Send IP number", 23) == 0)
{
// ...it was! Send an IP email...
send_ip();
// ...and delete the request email, so no further
// IP emails are sent...
write(pop_connection, "DELE ", 5);
write(
pop_connection,
message_number,
strlen(message_number));
write(pop_connection, "n", 1);
}
}while(!(server_reply[0] == '.' && server_reply[1] == ' '));
}
}
// ...sign off from the server...
write(pop_connection, "QUITn", 5);
// ...and close the connection...
disconnect_from_server(pop_connection);
}
// The functions below use some sockets stuff - I'm not going to comment it.
// If you want to know more, go here:
// [url="http://www.ecst.csuchico.edu/~beej/guide/net/html/"]http://www.ecst.csuchico.edu/~beej/guide/net/html/[/url]
static struct sockaddr_in setup_address(char *adress, int port)
{
struct sockaddr_in new_address;
memset((char *) &new_address, 0, sizeof(new_address));
new_address.sin_family = AF_INET;
new_address.sin_port = port;
if(adress != NULL)
{
struct hostent *host;
static struct in_addr saddr;
saddr.s_addr = inet_addr(adress);
if((int32_t) saddr.s_addr != -1)
{
new_address.sin_addr.s_addr = saddr.s_addr;
}else{
host = gethostbyname(adress);
if(host != NULL)
{
new_address.sin_addr.s_addr =
((struct in_addr *) *host->h_addr_list)->s_addr;
}else
new_address.sin_addr.s_addr = htonl(INADDR_ANY);
}
}else{
new_address.sin_addr.s_addr = htonl(INADDR_ANY);
}
return new_address;
}
static long connect_to_server(char *the_adress, long the_port_number)
{
long conn;
struct sockaddr_in adress;
int connected;
int on = 1;
conn = socket(AF_INET, SOCK_STREAM, 0);
if(conn < 0)
goto connect_to_server_fail_socket;
if(setsockopt(conn, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)) == -1)
goto connect_to_server_fail_setsockopt;
adress = setup_address(the_adress, the_port_number);
connected = connect(conn, (struct sockaddr *) &adress, sizeof(adress));
if(connected == -1)
goto connect_to_server_fail_connect;
fcntl(
conn,
F_SETFL,
fcntl(conn, F_GETFL, 0) | O_NONBLOCK);
return conn;
connect_to_server_fail_connect:
connect_to_server_fail_setsockopt:
close(conn);
connect_to_server_fail_socket:
return -1;
}
static void read_all_remaining_data(long connection)
{
char c;
while(read(connection, &c, 1) != -1)
;
}
static void disconnect_from_server(long connection)
{
close(connection);
}
[edit] I wish there was a "preview" feature on this webboard! I really do! [/edit]
------------------
Compilers - the ultimate god games.
[This message has been edited by Kidglove II (edited 04-22-2003).]