cURL / Mailing Lists / curl-library / Single Mail

curl-library

A better poor telnet example (I can use I think)

From: Dan Leonard <dleonard_at_ipa.cfa.harvard.edu>
Date: Mon, 19 May 2003 10:24:19 -0400

-----Original Message-----
From: Daniel Stenberg [mailto:daniel_at_haxx.se]
Sent: Friday, May 16, 2003 4:14 AM
To: libcurl Mailing list
Cc: Dan Leonard
Subject: Re: a poor telnet example -- but you don't have to enter the
password

On Thu, 15 May 2003, Dan Leonard wrote:

(Since this is a library-using app, I took this reply over to the
curl-library list.)

> I was trying to use the curl library for telnet where I don't have to
enter
> the password at a terminal; I do this because I want it to talk to a
router
> via an UI. I figured out a way, using "telnet://localhost", and a
write
> callback function. The biggest problem is that I have to assume the
socket
> connection back to the the telnetd daemon is "3", i.e. 0,1,2, are
stdin,
> stderr, stdout. This is a pretty good assumption, at least for a very
> short program.
>
> I see in 7.10 there might be ways of using "multi" to get file
desciptors,
> and to exit gracefully. This is a little new, as the system I am
working
> on is redhat 7.2 or 7.3, which has 7.9 curl naturally installed. I
guess I
> could install 7.10. Ayway, here is the poor example is attached.

>>libcurl's main paradigm is that it transfers files, either way. It is
not
>>very good at sending a little chunk now and little chunk then, as
telnet
>>requires.

>>To make libcurl more suitable for telnet, we should add two mechanisms
in the
>>API:

>> 1. Enable the application to tell the library that we have data to
send, or
>> that we don't have data to send. The current workings assume that
we will>>
>> continue sending data until there no longer is any, and then we're
done.

Yes, that's what I gathered.

>> 2. The reversed. Allow and application to tell the library that we
are not
>> prepared to receive any more data right now. The only kind of
>> flow-control an app has now, is to sleep in the callback before it
>> returns control back to the library and it certainly isn't very
nice.

>>In your telnet case, you could skip your work-around for file
descriptor 3 if
>>the first item in this list was added.

Yes. Actually I think I can use 7.8.1. By parsing through
/proc/<pid>/fd, you will always found "socket" at cnt six, after
".","..",stdin,stdio, stderr. Okay for my use, I'm going to just make a
system call.

Wondering now if I can capture more resposes and parse for some status
strings. either read(3,,,) or use write_data I should think.

I stll like using CURL because it does all protocols down to the
username. Making password work internally would help.

This version shuts-down gracefully by sending "quit\r" or "exit\r".

Dan

#include <stdio.h>
#include <string.h>

#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <errno.h>

#include <dirent.h>
#include <unistd.h>

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);

static CURL *curl;

size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp)
{
 DIR * dp;
 struct dirent *dirp;
 int fd, bytes,cnt;
 char dirs[128],dircmp[NAME_MAX], lbuf[2];
 static long socketdno;
 static char buflast;
 static int madewrite = 0;
 static int sockfdokay=0;

   if ( size*nmemb == 0 )
      return(0);

    printf("%c", *(char *)buffer);
    if ( *(char *)buffer == ' ' && buflast == ':' ) {
      if ( !madewrite ) {
         madewrite=1;
         sprintf(dirs,"/proc/%d/fd",getpid());
            dp = opendir(dirs);
         dp = opendir(dirs);
         if ( dp ) {
            dirp = (struct dirent *)1;
            for (cnt=0;dirp;) {
               dirp = readdir(dp);
               if ( dirp ) {
                 cnt++;
                 printf("dir is: %s cnt: %d\n",dirp->d_name,cnt);
                 sprintf(dirs,"/proc/%d/fd/%s",getpid(),dirp->d_name);
                 memset(dircmp,0,NAME_MAX);
                 if (readlink(dirs,dircmp,NAME_MAX) != -1 ) {
                    printf("link points to: %s\n", dircmp);
                    if ( !strncmp(dircmp,"socket:",strlen("socket:")) &&
cnt==6) {
                       printf("found socket at expected position: %d
link: %s\n",
                            cnt, dirp->d_name);
                       sockfdokay=1;
                    }
                 }
               }
            }
            printf("fd dir count %d\n",cnt);
            closedir(dp);
         }
         if ( cnt == 8 && sockfdokay == 1 ) { //
            bytes = write(3,"CogcoG\r\r",strlen("CogcoG\r\r"));
            printf("wrote: %d bytes sock: %d\n",bytes,3);
            bytes = 1;
            bytes = write(3,"who\r",strlen("who\r"));
            printf("wrote: %d bytes sock: %d\n",bytes,3);

#if 0
            while (bytes >0 ) {
               bytes = read(3,lbuf,1);
               printf("lub:: %c ::\n",lbuf);
            }
#endif
            bytes = write(3,"quit\r",strlen("quit\r"));
            printf("wrote: %d bytes sock: %d\n",bytes,3);
            bytes = write(3,"exit\r",strlen("exit\r"));
            printf("wrote: %d bytes sock: %d\n",bytes,3);
         }
    }
  }
  buflast = *(char *)buffer;
  /* printf("bytes in: %d\n",size*nmemb); */
  return(size*nmemb);
}

//int main(int argc, char **argv)
int main()
{
  FILE *hd_src;
  int res;

  curl = curl_easy_init();

    /* Get curl 7.7 from sunet.se's FTP site: */
    curl_easy_setopt(curl, CURLOPT_URL,
                     "telnet://localhost");

    curl_easy_setopt(curl, CURLOPT_USERPWD, "COG:CogcoG");

    curl_easy_setopt(curl, CURLOPT_VERBOSE, TRUE);

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);

    res = curl_easy_perform(curl);

    printf("res is: %d\n",res);

    /* always cleanup */
    curl_easy_cleanup(curl);

  /* fclose(ftpfile); close the local file */

  return 0;
}

-- 
 Daniel Stenberg -- curl: been grokking URLs since 1998
-------------------------------------------------------
This SF.net email is sponsored by: If flattening out C++ or Java
code to make your application fit in a relational database is painful, 
don't do it! Check out ObjectStore. Now part of Progress Software.
http://www.objectstore.net/sourceforge
Received on 2003-05-19