Help - Search - Members - Calendar
Full Version: Finding Out My External IP
Ambrosia Software Web Board > General Interest > Just Tech
Clueless
Following situation:
we have a DrayTek Vigor 2200 ADSL router which... well, routes our ADSL. Now, I want to SSH or FTP my home machine which has a LAN address (the 192.168.x.x ones) by the router's external IP, which is not a problem as long as I know the actual external IP. I can obtain that by entering the router's config or by means of several webtools. As long as I'm on my home machine, that is.

The problem starts here: I'm not at home. I want to FTP my machine, but I don't know our LAN's external IP. I figured I could bring my Mac to send a mail with the actual external IP on request to a specified e-mail address. Well, it could if itself knew its IP.

So, the questions are:
  • ::solved already::How can I make my Mac find out its external IP at a specific point in time? Preferrably a command line tool so I can grep the needed information.
  • ::solved, but not perfect::How do I set the system up to scan the mail inbox on scheduled times and search the header of the mail for a certain keyword? (Probably grep again, just asking for an easier solution.) Again, I'd like to use a shell script, so command line directions would be greatly appreciated.
  • ::solved, but not perfect::How do I make the system send a mail with the IP returned by the first step? (Once again, command-line would be nice.)
Thanks in advance, please answer even if all you've got is a vague idea.

------------------
Eat, sleep, eat, sleep?
Blödpinsel / Blood Würst

[edited for stupid list function]
[edited for solving of point 1]
[edited for rest]

[This message has been edited by Clueless (edited 04-19-2003).]
sinclair44
Hrm. You could curl http://www.whatismyip.com/ and grep that.

CODE
curl [url="http://www.whatismyip.com"]www.whatismyip.com[/url]  | grep [i]regex[/i]


------------------
In the beginning, all was NULL, or perhaps (void*).
-- Vega Strike introduction
One, Two, Three, Pfhor
iDevGames... do uDevGames?
Mahayana
Unfortunately, I do not know of a command-line tool, but I know of a program for OS X that outputs both your LAN and WAN (external) IP. It's a great little app called "MyIP" by Vapor Software. It's freeware and I think you can get it at the Macupdate webpage. (In fact, I think this address is a direct link to the download page.) Hope this helps!

------------------
Shnobe.
Clueless
Yay! Thanks, sinclair! This does the job:
CODE
curl -s [url="http://www.whatismyip.com"]www.whatismyip.com[/url]  | grep "Your ip is" | awk '{print $4}'

Thank you too, Mahayana, but that thingy you linked to only gives me my local IP.

Keep it coming people, only problem 1 is solved.

------------------
Eat, sleep, eat, sleep?
Blödpinsel / Blood Würst

[edit ubb]

[This message has been edited by Clueless (edited 04-18-2003).]
PCheese
Or, if you have access to webserver that lets you upload PHP files, try this:

Upload an empty text file named "externalip.txt" to the root directory of the server and CHMOD 777 it.

Upload a file named "myip.php" containing this code:

CODE
<?php
$filename = "externalip.txt";
if ($action == "set") {
    $fp = fopen("$filename", "w") or die("Couldn't open $filename");
    fwrite($fp, $REMOTE_ADDR);
    fclose($fp);
    echo "IP ($REMOTE_ADDR";
    echo ") set successfully!";
    exit;
}
$contents = file("$filename");
$homeip = $contents[0];
header("Location: <A HREF="http://$homeip");" TARGET=_blank>http://$homeip");</A>
?>


When you go to http://www.yourdomain.com/myip.php?action=set, it gets the IP of the computer accessing the site and saves it. When you go to http://www.yourdomain.com/myip.php, it redirects you to http://yourip/, which is useful if you have a website. You can change header("Location: http://$homeip"); to header("Location: ftp://$homeip"); if you want to be redirected to your site by FTP instead of by HTTP. You could also go to http://www.yourdomain.com/externalip.txt to display the ip that was previously set.

Now the problem is getting your computer to access the page so the IP gets set regularly. You could probably set up a cron job to do that (like sinclair's idea), or be like me and save this AppleScript as an application then add it to your login items:
CODE
set the target_URL to "http://www.yourdomain.com/myip.php?action=set"
set the destination_file to ((path to desktop as string) & "myip_cache.html")

tell application "URL Access Scripting"
    download target_URL to file destination_file replacing yes
end tell

tell application "Finder" to delete alias destination_file


You can check out an example here that sends you to my computer (if it's on).

------------------
A Ferazel Site | Another Ferazel Site | The Best Ferazel Site

[This message has been edited by PCheese (edited 04-18-2003).]
Clueless
Hey, thanks! But I'm afraid I don't have the possibility to host anything on the web right now and to be honest, I was hoping to get this done without excursions into php or anything funky like that.

Concerning my initial idea; so far I've figured out that fetchmail and sendmail will do the job, just how? The fetchmail man page alone is about fifty metres long...

------------------
Eat, sleep, eat, sleep…
Blödpinsel / Blood Würst
Mahayana
QUOTE
Originally posted by Clueless:
Thank you too, Mahayana, but that thingy you linked to only gives me my local IP.

Are you sure? I'm behind a router and it gives me both my LAN and WAN IP.

------------------
Shnobe.
sinclair44
QUOTE
Originally posted by Clueless:
Concerning my initial idea; so far I've figured out that fetchmail and sendmail will do the job, just how? The fetchmail man page alone is about fifty metres long...


I'm running sendmail on my computer right now. It allows you to use your computer as if it were an SMTP server. To enable it, edit /etc/hostconfig to change the line:

MAILSERVER=-NO-

to be:

MAILSERVER=-YES-

And then either restart your computer or issue this command:

sudo /System/Library/StartupItems/Sendmail/Sendmail start

When sendmail is running, your computer is actually an SMTP server. Try putting "localhost" in your e-mail program as the outgoing server. As for security, by default no one but localhost is allowed to use it. This can be changed (KEEP IT AS DEFAULT UNLESS YOU NEED TO!!) but I don't remember how.

If you shutdown, sendmail will automatically be restarted by SystemStarter during boot, so the above command is not nessecary more than once. To stop sendmail for good, issue:

/System/Library/StartupItems/Sendmail/Sendmail stop

And change the /etc/hostconfig line back to -NO-. (You may have to restart, but I don't think so.)

------------------
In the beginning, all was NULL, or perhaps (void*).
-- Vega Strike introduction
One, Two, Three, Pfhor
iDevGames... do uDevGames?

[This message has been edited by sinclair44 (edited 04-18-2003).]
Catfish_Man
QUOTE
Originally posted by sinclair44:
Hrm. You could curl http://www.whatismyip.com/ and grep that.

CODE
curl [url="http://www.whatismyip.com"]www.whatismyip.com[/url]  | grep [i]regex[/i]




Thanks! I've been looking for something to do this.

------------------
Clueless
Yay me! I did it.
CODE
#! /bin/bash

       ## Mail.app laedt neue Nachrichten herunter

osascript -e 'tell application "Mail"
       check for new mail
       end tell'

       ## Wartet vier Sekunden, damit Mail genug Zeit zum Herunterladen bekommt.

sleep 4

       ## Grep sucht die Zeile, die den Betreff "Externe IP schicken" enthaelt und teilt diesen
       ## String der Variablen EXTERNEIP zu. (In der Liste "mbox".)

EXTERNEIP="`cat ~/Library/Mail/POP:Krautilein@pop.gmx.net/inbox.mbox/mbox | grep -i "Externe IP schicken"`"

       ## Pruefung, ob Variable EXTERNEIP eine Betreffzeile enthaelt oder NULL ist. (-z)

if [ -z "$EXTERNEIP" ]; then

       ## Wenn EXTERNEIP doch NULL ist, also keine Anforderung ueber Mail vorhanden, dann schaltet das Skript ab.

exit 1

       ## Ansonsten...
else

       ## Momentane externe IP-Adresse ueber [url="http://www.WhatIsMyIP.com"]www.WhatIsMyIP.com[/url]  abfragen und ueber Applescript als variable extip festlegen.

osascript -e 'do shell script "extip"
       copy the result to extip

       --Anweisung fuer Mail.app, eine neue Nachricht mit der momentanen IP als Betreff anzulegen.--
     
tell application "Mail"
       set ipmessage to make new outgoing message with properties {subject:extip, sender:"krautilein@gmx.de"}
       tell ipmessage
       make new to recipient at end of to recipients with properties {address:"Krautilein@gmx.de"}
       end tell
       send ipmessage
end tell'
fi
Sorry, commented in German. I just feared I might forget what I was doing, given the time was past 3 in the morning.

So basically this checks the mailbox for a message with the subject "Externe IP schicken" (send external IP), if it finds it, it connects to www.whatismyip.com and retrieves the line it needs (that's what the shell script "extip" does in the Applescript part), then makes a new mail with that line as subject and sends it back to myself. Cool, just how I wanted it.

Thanks everybody, especially sinclair. I'll look if I can refine the thing so that it doesn't need any GUI elements anymore at all.

------------------
Eat, sleep, eat, sleep?
Blödpinsel / Blood Würst

[edited for clarity and sleep deficit]

[This message has been edited by Clueless (edited 04-19-2003).]
Kidglove2
I have three ideas.
[list=1]
[*]Instead of it emailing on a per-request basis, how about setting up a cron event that checks the IP every, say, X minutes/hours. If the IP has changed from the last time it checked, a new mail is sent to a specific email adress with the new IP.
[*]Or, if you have access to a web site that you can access from anywhere, have the IP number posted to web site by triggering a shell script that uploads the IP number via FTP.
[*]And since I'm a programmer I've thought up the following hi-tech solution:
You open a specific UDP port with a high number from your ADSL router to the same UDP port number on your machine. You then have a small program that listens on that port and if it gets a packet on that port, it immediately answers with something that is unique to your machine (your ethernet adress or something). On the other end, all you have to do is write down (or have the program somehow remember) one of your old IP adresses. The program scans the entire network that that IP belongs to for any replies that has the correct unique identifier.
[/list=a]

The last solution might be a bit overcomplicated, but it would work. If it gives anyone else an idea of how to do it in a simpler way, that's good too.

'glove
[edit] it took me a while to write all this down, it seems [/edit]
------------------
Compilers - the ultimate god games.

[This message has been edited by Kidglove II (edited 04-19-2003).]
Clueless
QUOTE
Originally posted by Kidglove II:
Instead of it emailing on a per-request basis, how about setting up a cron event that checks the IP every, say, X minutes/hours. If the IP has changed from the last time it checked, a new mail is sent to a specific email adress with the new IP.
Nah, since this script sends the mail to my regular e-mail address, I'd rather not have it spamming the inbox with IPs every quarter hour. To be exact, I'll set it up to check for requests every half hour or so...
QUOTE
Or, if you have access to a web site that you can access from anywhere, have the IP number posted to web site by triggering a shell script that uploads the IP number via FTP.
Don't have no website.
QUOTE
And since I'm a programmer I've thought up the following hi-tech solution:
You open a specific UDP port with a high number from your ADSL router to the same UDP port number on your machine. You then have a small program that listens on that port and if it gets a packet on that port, it immediately answers with something that is unique to your machine (your ethernet adress or something). On the other end, all you have to do is write down (or have the program somehow remember) one of your old IP adresses. The program scans the entire network that that IP belongs to for any replies that has the correct unique identifier.
Well, since I'm not a programmer...
No, seriously, to have that working (by what I understand), it would need a request for answer to the open port. Since I cannot request when the router is not "dialed in"... well, you get it. To clarify: the router opens a connection to the ISP if one of the computers request it to do so. This is not a constant connection, but times out after 180 seconds of inactivity. After that period of time, it has to open a new connection and gets a new external IP assigned by the ISP.

------------------
Eat, sleep, eat, sleep…
Blödpinsel / Blood Würst
Kidglove2
QUOTE
Originally posted by Clueless:
Nah, since this script sends the mail to my regular e-mail address, I'd rather not have it spamming the inbox with IPs every quarter hour. To be exact, I'll set it up to check for requests every half hour or so...


As I stated: it only has to send a new email if the IP changes - not when it stays the same.

QUOTE
Originally posted by Clueless:
Well, since I'm not a programmer...


Fair enough, I suppose.

QUOTE
Originally posted by Clueless:
No, seriously, to have that working (by what I understand), it would need a request for answer to the open port. Since I cannot request when the router is not "dialed in"... well, you get it. To clarify: the router opens a connection to the ISP if one of the computers request it to do so. This is not a constant connection, but times out after 180 seconds of inactivity. After that period of time, it has to open a new connection and gets a new external IP assigned by the ISP.


But if your machine isn't "dialed in", you're screwed anyway, since you can't ftp into a machine that isn't connected to the internet.

Anyway, all you'd have to do to prevent this is to have the same program send a ping packet or whatever to some machine on the internet every 100 seconds or so. This will prevent your ADSL connection to die.

I've been thinking about these things for a while, mainly because I'm fed up with the current IM apps out there and was trying to figure out a way to make an IM app that wouldn't require a coordinating server. I've since more or less given up on the idea of making the IM app (too much hassle, noone would be interested in another IM app that would be using another protocol that would be incompatible with all the other protocols out there), but I've kept the ideas on how to identify a person who is on a number of different IP numbers in my mind. They might become useful at some point. Who knows?

'glove

------------------
Compilers - the ultimate god games.

[This message has been edited by Kidglove II (edited 04-20-2003).]
Kidglove2
CODE
#!/bin/bash
MY_IP=(curl -s [url="http://www.whatismyip.com"]www.whatismyip.com[/url]   | grep "Your ip is" | awk '{print $4}')
(echo "Subject: IP number"; echo "The IP number is" $MY_IP) | /usr/lib/sendmail <your email address goes here>


Something like that? Assuming that sendmail is set up properly...

'glove
[edit] the line was too long... [/edit]
------------------
Compilers - the ultimate god games.

[This message has been edited by Kidglove II (edited 04-20-2003).]
Clueless
QUOTE
Originally posted by Kidglove II:
But if your machine isn't "dialed in", you're screwed anyway, since you can't ftp into a machine that isn't connected to the internet.
Actually... no. If the machine checks for mail every 15 minutes or so, it is online for three minutes. I just have to hit those three minutes to ftp or ssh my computer. If I do something over ftp the connection will stay open until I'm done.
QUOTE
As I stated: it only has to send a new email if the IP changes - not when it stays the same.
Yes, but the IP changes everytime it opens a connection.

And I'd rather not have it ping all the time to keep the connection going, as that's gonna cost extra with my ISP. Yeah, it sucks - but is the only "low cost" DSL provider in the area.

------------------
Eat, sleep, eat, sleep…
Blödpinsel / Blood Würst
Kidglove2
QUOTE
Originally posted by Clueless:
Yes, but the IP changes everytime it opens a connection.


Ah - but if you kept the connection open using the pinging technique, the IP wouldn't change that often. (see the next reply...)

QUOTE
Originally posted by Clueless:
And I'd rather not have it ping all the time to keep the connection going, as that's gonna cost extra with my ISP. Yeah, it sucks - but is the only "low cost" DSL provider in the area.


They charge you for the connection time? Didn't know that - my ISP doesn't. Then the ping-technique is not useful.

'glove

------------------
Compilers - the ultimate god games.
Clueless
QUOTE
Originally posted by Kidglove II:
They charge you for the connection time? Didn't know that - my ISP doesn't. Then the ping-technique is not useful.
Yeah, it's the horror. I still got to talk my parents into getting the flatrate plan, but they refuse to see why I need a 24/7 connection... Now, they'll give in sooner or later. Then I'll hopefully have a fixed IP as well.

------------------
Eat, sleep, eat, sleep…
Blödpinsel / Blood Würst
Kidglove2
QUOTE
Originally posted by Clueless:
Yeah, it's the horror. I still got to talk my parents into getting the flatrate plan, but they refuse to see why I need a 24/7 connection... Now, they'll give in sooner or later. Then I'll hopefully have a fixed IP as well.


Heh.

I have a flatrate ADSL connection, but I still don't have a fixed IP - my IP changes every so often when I am forced to log in to the ISP again. This appears to happen at random times, and I need to use a web browser to do it. It's usually a couple of days between logins, but my IP changes each time.

Anyway, would you care to comment on my code block above?

'glove

------------------
Compilers - the ultimate god games.
Clueless
QUOTE
Originally posted by Kidglove II:
Anyway, would you care to comment on my code block above?
To be honest, I gave up on sendmail about a mile down the man page. I went for the uglier, but easier solution: Mail.app.

Also, that piece of code (half of which obviously is blatantly copy-pasted... ) leaves the checking for requests aspect untouched.

Do you know of any useful sendmail tutorials? Everything I found either didn't work for some reason or was pre-Jaguar.

------------------
Eat, sleep, eat, sleep…
Blödpinsel / Blood Würst
Kidglove2
[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).]
Kidglove2
This post is partially a bump to make sure clueless has seen the code above, and also a suggestion that rewriting this:

CODE
    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);

into this:
CODE
    ip_file =
 popen(
     "curl -s [url="http://www.whatismyip.com"]www.whatismyip.com[/url]  | "
     "grep "Your ip is" | "
     "awk '{print $4}'", "r");
    if(ip_file == NULL)
 return;
    
    for(i = 0; i == 0 || ip_string[i-1] != 'n'; i++)
 fread(&(ip_string[i]), sizeof(char), 1, ip_file);
    ip_string[i] = '';
    pclose(ip_file);

will remove the use of a temporary file.

'glove

------------------
Compilers - the ultimate god games.
Clueless
Hey, cool! Trying this now...

[edit: ok, help me please. The command line gcc compiler barfs on the -03 option, and Project Builder... well, I'm not a programmer. Please, some more directions.]

------------------
Eat, sleep, eat, sleep?
Blödpinsel / Blood Würst

[This message has been edited by Clueless (edited 04-24-2003).]
Kidglove2
QUOTE
Originally posted by Clueless:
[edit: ok, help me please. The command line gcc compiler barfs on the -03 option, and Project Builder... well, I'm not a programmer. Please, some more directions.]


You should know that it's -O3, not -03 (the capital letter o, not zero). Besides, it's not like it matters - you can leave that out if you like.

[edit]Explanation: a minimal compile line would be "gcc <your file name>". That would create a file called "a.out" which is your executable. The "-lc" might be neccesary (haven't tested), and the "-o" flag is just so you don't have to rename your executable file. [/edit]

'glove
[edit] I wish there was a preview function on this board... [/edit]
------------------
Compilers - the ultimate god games.

[This message has been edited by Kidglove II (edited 04-24-2003).]
Clueless
QUOTE
Originally posted by Kidglove II:
a minimal compile line would be "gcc <your file name>"
This is what it says:
QUOTE
[WtIP:~/desktop] admin% gcc ipsender
ld: ipsender bad magic number (not a Mach-O file)


------------------
Eat, sleep, eat, sleep…
Blödpinsel / Blood Würst
Kidglove2
Ok. My bad. Here's a step-by-step instruction on how to do it:

[list=1]
[*]Take the source code from the post above and store it in a plain text file that you make sure has the name "ipsender.c". Save it in your home folder for simplicity.
[*]Change the SMTP_SERVER_ADDRESS etc. to reflect your own server settings.
[*]Open a terminal.
[*]Enter the following into the terminal, excluding the quotes, and hit enter: "gcc -o ipsender ipsender.c"
[*]When you get a new prompt, there should be a new file in your home directory called "ipsender".
[*]To activate the program, you have to open a terminal and type in "ipsender".
[*]To deactivate the program, you have to either use the "kill" command in the terminal, or hit Ctrl-C in the terminal you started the program in.
[/list=a]

Hope that helps better.

'glove

------------------
Compilers - the ultimate god games.
[edit] I wish there was a preview feature on this board. [/edit]
Clueless
Hehe, I didn't ask for a command line tutorial for a doofus. Well, thanks for bearing with me, I'll try this now.

[edit:
CODE
[WtIP:~] admin% gcc -o ipsender ipsender.c
ipsender.c:137: stray '' in program
ipsender.c:138: stray '' in program
ipsender.c:139: stray '' in program
ipsender.c:140: stray '' in program
ipsender.c:141: stray '' in program
ipsender.c:142: stray '' in program
ipsender.c:143: stray '' in program
ipsender.c:144: stray '' in program
ipsender.c:136: stray '' in program
ipsender.c: In function `send_ip':
ipsender.c:71: `i' undeclared (first use in this function)
ipsender.c:71: (Each undeclared identifier is reported only once
ipsender.c:71: for each function it appears in.)
[WtIP:~] admin%

Could this result from bad line endings introduced by SimpleText? I created the .c file by pasting into pico in Terminal, though.

------------------
Eat, sleep, eat, sleep?
Blödpinsel / Blood Würst

[This message has been edited by Clueless (edited 04-24-2003).]
Kidglove2
/me sighs...

Sometimes, computers just plain suck.

Anyway - here is a stuffed version of the file above, which doesn't use a temporary file. (I'm not vouching for how long that file will stay at that location, but it should be safe for a couple of weeks.)

You'll have to compile it yourself, since I don't think you're willing to give me your email password etc. but this should make it easier to compile. I tried compiling it myself with the simple call "gcc -o <output file name> untitled.c", and it compiled.

'glove

------------------
Compilers - the ultimate god games.
[edit] I wish there was a preview feature on this board. [/edit]
Kidglove2
QUOTE
Originally posted by Clueless:
CODE
ipsender.c:137: stray '' in program
ipsender.c:138: stray '' in program
ipsender.c:139: stray '' in program
ipsender.c:140: stray '' in program
ipsender.c:141: stray '' in program
ipsender.c:142: stray '' in program
ipsender.c:143: stray '' in program
ipsender.c:144: stray '' in program
ipsender.c:136: stray '' in program


To me, this says that there is _something_ wrong with the POP_CHECK_RESULT macro's definition. It's probably that Terminal and pico disagree on what terminates a line, or something.

QUOTE
Originally posted by Clueless:
CODE
ipsender.c: In function `send_ip':
ipsender.c:71: `i' undeclared (first use in this function)
ipsender.c:71: (Each undeclared identifier is reported only once
ipsender.c:71: for each function it appears in.)



This says that you forgot to add a line "long i;" in the send_ip function when you copy-pasted the popen code into it. My fault - I simply forgot that.

Both these things should be fixed by simply downloading the file in my last post.

'glove

------------------
Compilers - the ultimate god games.
[edit] I wish there was a preview feature on this board. [/edit]
Clueless
Cool. It compiled. Now all I have to do is send me a mail and wait 15 minutes.

Hope it works, but many thanks for your efforts anyhow.

[edit: refresh, topic, refresh]

------------------
Eat, sleep, eat, sleep?
Blödpinsel / Blood Würst

[This message has been edited by Clueless (edited 04-25-2003).]
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.