Logo Search packages:      
Sourcecode: ksh version File versions

ifs_http.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1990-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
/*
 * File: ifs_httpcs.c
 */

#include "ifs_agent.h"
#include <stdio.h>

struct {
    int           version;
} HttpData;

/*
 *name: HttpConvert
 *    create a file of reference entries from the HTML document.
 */
int
HttpConvert( srcfile, htmlfile, linkfile )
char  *srcfile;
char  *htmlfile;
char  *linkfile;
{
    FILE    *fsrc, *fhtml, *flink;
    char    buf[ STRLEN ];
    char    *ptr, *p1, *p2;
    int           len;
    int           textflag = 0;

    if( (fsrc = fopen( srcfile, "r" )) == NULL ) {
      return -1;
    }
    if( (fhtml = fopen( htmlfile, "w" )) == NULL ) {
      fclose( fsrc );
      return -1;
    }
    if( (flink = fopen( linkfile, "w" )) == NULL ) {
      fclose( fhtml );
      fclose( fsrc );
      return -1;
    }

    /* parse header */
    while( fgets( buf, sizeof(buf), fsrc ) != NULL ) {
      fprintf( flink, "%s", buf );
      if( buf[0] == '\n' || buf[0] == '\r' )
          break;
      if( strncmp( buf, "Content-Type: text", 18 ) == 0 )
          textflag = 1;
    }

    if( textflag ) {
      /* parse htmlfile */
      while( fgets( buf, sizeof(buf), fsrc ) != NULL ) {
          fprintf( fhtml, "%s", buf );
          ptr = buf;
          while( (p1 = strchr( ptr, '<' )) != NULL &&
               (p2 = strchr( p1,  '>' )) != NULL ) {
            p1++;
            *p2++ = '\0';

            /* <a href="..."> */
            if( (*p1 == 'a' || *p1 == 'A') && p1[1] == ' ' )
                fprintf( flink, "<%s>\n", p1 );
            ptr = p2;
          }
      }
    } else {
      /* dump binary data */
      while( (len = fread( buf, 1, sizeof(buf), fsrc )) > 0 )
          fwrite( buf, 1, len, fhtml );
    }

    fclose( flink );
    fclose( fhtml );
    fclose( fsrc );
    return 0;
}

/*
 *name: HttpXfer
 *    transfer a file from web server
 */
int
HttpXfer( srv, rpath, linkfile, tmpfile )
struct server_info *srv;
char  *rpath;
char  *linkfile;
char  *tmpfile;
{
    struct mount_item   *mitem = srv->mitem;
    NetFile *nFile;
    FILE    *fout;
    char    buf[ STRLEN ], *ptr;
    char    line[ STRLEN ];
    int           port, len, ans = -1;
    
    if( (port = mitem->port) <= 0 )
      port = 80;
    if( (fout = fopen( tmpfile, "w" )) == NULL ) {
      logit( "<http>: tmpfile open error\n" );
      return -1;
    }
    if( (nFile = NetConnect( srv, mitem->host, port )) == NULL ) {
      fclose( fout );
      logit( "<http>: connect error\n" );
      return -1;
    }
    sfsprintf( buf, sizeof(buf), "GET %s HTTP/1.0\n", rpath );
    NetWrite( nFile, buf, strlen(buf) );
    logit( buf );

#if 0 /* -------- ignore this feature -------- */
    /* If-Modified-Since: <Last-Modified> */
    if( (fp = fopen( linkfile, "r" )) != NULL ) {
      while( fgets( line, sizeof(line), fp ) != NULL && line[0] != '\n' ) {
          if( strncasecmp( line, "Last-Modified: ", 15 ) == 0 ) {
            sfsprintf( buf, sizeof(buf), "If-Modified-Since: %s", line+15 );
            NetWrite( nFile, buf, strlen(buf) );
            debug_logit( buf );
            break;
          }
      }
      fclose( fp );
    }
#endif

    /* Cookie: <cookie-value> */
    if( DataEntryQuery( srv->lpath, "cookie", line, sizeof(line) ) > 0 ) {
      sfsprintf( buf, sizeof(buf), "Cookie: %s\n", line );
      NetWrite( nFile, buf, strlen(buf) );
      debug_logit( buf );
    }

    ptr = "Accept: */*\n\n";
    NetWrite( nFile, ptr, strlen(ptr) );
    debug_logit( ptr );

    /* reply: HTTP/1.0 200 Document follows */
    NetGets( nFile, line, sizeof(line) );
    logit( line );
    if( (ptr = strchr( line, ' ' )) != NULL ) {
      ans = (int)strtol( ptr+1, (char**)0, 0 );
    }
    fputs( line, fout );
    while( (len = NetRead( nFile, line, sizeof(line) )) > 0 ) {
      fwrite( line, 1, len, fout );
    }
    NetClose( nFile );
    fclose( fout );
    return ans;
}

/*
 *name: HttpXferDir
 *    transfer URL as a directory
 */
int
HttpXferDir( srv, tmpfile )
struct server_info *srv;
char  *tmpfile;
{
    char    rpath[ STRLEN ];
    char    linkfile[ STRLEN ];
    char    *lpath = srv->lpath;
    int           ans;

    sfsprintf( rpath, sizeof(rpath), "%s/", srv->rpath );
    sfsprintf( linkfile, sizeof(linkfile), "%s/._dir", lpath );
    ans = HttpXfer( srv, rpath, linkfile, tmpfile );
    if( ans < 300 ) {         /* 2xx Successful, 1xx Informational */
      if( chdir( lpath ) ) {
          MakePath( linkfile );
          if( chdir( lpath ) )
            return 404;       /* 404 Not Found */
      }
      HttpConvert( tmpfile, "index.html", "._dir" );
      symlink( srv->mitem->timeout, "._cache_time" );
    }
    return ans;
}

/*
 *name: HttpXferFile
 *    transfer URL as a text file
 */
int
HttpXferFile( srv, tmpfile )
struct server_info *srv;
char  *tmpfile;
{
    char    linkfile[ STRLEN ];
    char    *lpath = srv->lpath;
    char    *ptr;
    int           ans;

    if( (ptr = strrchr( lpath, '/' )) == NULL )
      return -1;
    *ptr = '\0';
    sfsprintf( linkfile, sizeof(linkfile), "%s/._dir.%s", lpath, ptr+1 );
    *ptr = '/';

    ans = HttpXfer( srv, srv->rpath, linkfile, tmpfile );
    if( ans < 300 ) {         /* 2xx Successful, 1xx Informational */
      MakePath( lpath );
      HttpConvert( tmpfile, lpath, linkfile );
    }
    return ans;
}

/*
 *name: HttpGetFile
 *    validate a URL file
 */
int
HttpGetFile( srv )
struct server_info *srv;
{
    char    tmpfile[ STRLEN ];
    char    *rpath, *ptr;
    int           ans;

    MakeTmpFile( srv->lpath, tmpfile, sizeof(tmpfile) );
    rpath = srv->rpath;
    if( (ptr = strrchr( rpath, '/' )) != NULL &&
      strcmp( ptr, "/index.html" ) == 0 ) {
      /* try get the directory html file (.../index.html) */
      *ptr = '\0';
      ptr = strrchr( srv->lpath, '/' );
      *ptr = '\0';
    }
    if( *rpath == '\0' || DashD( srv->lpath ) ) {
      ans = HttpXferDir( srv, tmpfile );
    } else if( DashF( srv->lpath ) ) {
      ans = HttpXferFile( srv, tmpfile );
    } else {
      ans = HttpXferFile( srv, tmpfile );
      if( ans >= 400 ) {            /* 4xx, 5xx (ex: 404 Not Found) */
          return -1;
      } else if( ans >= 300 ) {     /* 3xx Redirection */
          ans = HttpXferDir( srv, tmpfile );
      }
    }
    unlink( tmpfile );
    return( ans >= 400 ? -1 : 0 );
}

/*
 *name: HttpUserDef
 *    query/modify the extra header of http protocol.
 *    (ex: Cookie ...)
 */
int
HttpUserDef( srv, argc, argv )
struct server_info *srv;
int   argc;
char  *argv[];
{
    char    buf[ STRLEN ];
    char    *fpath, *key, *data;

    if( argc < 2 ) {
      sfsprintf( csusrmsg, sizeof(csusrmsg), "1 Usage: userdef local-path key (-|data)" );
      return 0;
    }
    fpath = argv[0];
    key = argv[1];
    if( argc < 3 ) {          /* query data */
      if( DataEntryQuery( fpath, key, buf, sizeof(buf) ) >= 0 ) {
          sfsprintf( csusrmsg, sizeof(csusrmsg), "0 %s %s %s", fpath, key, buf );
      } else {
          sfsprintf( csusrmsg, sizeof(csusrmsg), "1 %s %s not-found", fpath, key );
      }
    } else if( *argv[2] == '-' ) {  /* delete header */
      if( DataEntryDelete( fpath, key ) == 0 ) {
          sfsprintf( csusrmsg, sizeof(csusrmsg), "0 %s %s deleted", fpath, key );
      } else {
          sfsprintf( csusrmsg, sizeof(csusrmsg), "1 %s %s not-found", fpath, key );
      }
    } else {
      data = argv[2];
      DataEntryInsert( fpath, key, data, strlen(data)+1 );
      sfsprintf( csusrmsg, sizeof(csusrmsg), "0 %s %s inserted", fpath, key );
    }
    return 0;
}

int
HttpNop()
{
    return 0;
}

int
HttpInit( tbl )
struct agent_item *tbl;
{
    tbl->localdata      = (char *) &HttpData;
    tbl->connect  = HttpNop;
    tbl->disconnect     = HttpNop;
    tbl->listdents      = HttpGetFile;
    tbl->getfile  = HttpGetFile;
    tbl->putfile  = HttpNop;
    tbl->userdef  = HttpUserDef;
    return 0;
}


Generated by  Doxygen 1.6.0   Back to index