Subversion Repositories shark

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 *   httpget.c
 *
 *   Oliver Fromme  <oliver.fromme@heim3.tu-clausthal.de>
 *   Wed Apr  9 20:57:47 MET DST 1997
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/errno.h>
extern int errno;

#include "mpg123.h"

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif

void writestring (int fd, char *string)
{
        int result, bytes = strlen(string);

        while (bytes) {
                if ((result = write(fd, string, bytes)) < 0 && errno != EINTR) {
                        perror ("write");
                        exit (1);
                }
                else if (result == 0) {
                        fprintf (stderr, "write: %s\n",
                                "socket closed unexpectedly");
                        exit (1);
                }
                string += result;
                bytes -= result;
        }
}

void readstring (char *string, int maxlen, FILE *f)
{
        char *result;

        do {
                result = fgets(string, maxlen, f);
        } while (!result  && errno == EINTR);
        if (!result) {
                fprintf (stderr, "Error reading from socket or unexpected EOF.\n");
                exit (1);
        }
}

char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *port)
{
        char *cptr;
        struct hostent *myhostent;
        struct in_addr myaddr;
        int isip = 1;

        if (!(strncmp(url, "http://", 7)))
                url += 7;
        cptr = url;
        while (*cptr && *cptr != ':' && *cptr != '/') {
                if ((*cptr < '0' || *cptr > '9') && *cptr != '.')
                        isip = 0;
                cptr++;
        }
        if (!(*hname = strndup(url, cptr - url))) {
                *hname = NULL;
                return (NULL);
        }
        if (!isip) {
                if (!(myhostent = gethostbyname(*hname)))
                        return (NULL);
                memcpy (&myaddr, myhostent->h_addr, sizeof(myaddr));
                *hip = myaddr.s_addr;
        }
        else
                if ((*hip = inet_addr(*hname)) == INADDR_NONE)
                        return (NULL);
        if (!*cptr || *cptr == '/') {
                *port = 80;
                return (cptr);
        }
        *port = atoi(++cptr);
        while (*cptr && *cptr != '/')
                cptr++;
        return (cptr);
}

char *proxyurl = NULL;
unsigned long proxyip = 0;
unsigned int proxyport;

#define ACCEPT_HEAD "Accept: audio/mpeg, audio/x-mpegurl, */*\r\n"

FILE *http_open (char *url)
{
        char *purl, *host, *request, *sptr;
        int linelength;
        unsigned long myip;
        unsigned int myport;
        int sock;
        int relocate, numrelocs = 0;
        struct sockaddr_in server;
        FILE *myfile;

        if (!proxyip) {
                if (!proxyurl)
                        if (!(proxyurl = getenv("MP3_HTTP_PROXY")))
                                if (!(proxyurl = getenv("http_proxy")))
                                        proxyurl = getenv("HTTP_PROXY");
                if (proxyurl && proxyurl[0] && strcmp(proxyurl, "none")) {
                        if (!(url2hostport(proxyurl, &host, &proxyip, &proxyport))) {
                                fprintf (stderr, "Unknown proxy host \"%s\".\n",
                                        host ? host : "");
                                exit (1);
                        }
                        if (host)
                                free (host);
                }
                else
                        proxyip = INADDR_NONE;
        }
       
        if ((linelength = strlen(url)+200) < 1024)
                linelength = 1024;
        if (!(request = malloc(linelength)) || !(purl = malloc(1024))) {
                fprintf (stderr, "malloc() failed, out of memory.\n");
                exit (1);
        }
        strncpy (purl, url, 1023);
        purl[1023] = '\0';
        do {
                strcpy (request, "GET ");
                if (proxyip != INADDR_NONE) {
                        if (strncmp(url, "http://", 7))
                                strcat (request, "http://");
                        strcat (request, purl);
                        myport = proxyport;
                        myip = proxyip;
                }
                else {
                        if (!(sptr = url2hostport(purl, &host, &myip, &myport))) {
                                fprintf (stderr, "Unknown host \"%s\".\n",
                                        host ? host : "");
                                exit (1);
                        }
                        if (host)
                                free (host);
                        strcat (request, sptr);
                }
                sprintf (request + strlen(request),
                        " HTTP/1.0\r\nUser-Agent: %s/%s\r\n",
                        prgName, prgVersion);
                strcat (request, ACCEPT_HEAD);
                strcat (request, "\r\n");
                server.sin_family = AF_INET;
                server.sin_port = htons(myport);
                server.sin_addr.s_addr = myip;
                if ((sock = socket(PF_INET, SOCK_STREAM, 6)) < 0) {
                        perror ("socket");
                        exit (1);
                }
                if (connect(sock, (struct sockaddr *)&server, sizeof(server))) {
                        perror ("connect");
                        exit (1);
                }
                writestring (sock, request);
                if (!(myfile = fdopen(sock, "rb"))) {
                        perror ("fdopen");
                        exit (1);
                };
                relocate = FALSE;
                purl[0] = '\0';
                readstring (request, linelength-1, myfile);
                if ((sptr = strchr(request, ' '))) {
                        switch (sptr[1]) {
                                case '3':
                                        relocate = TRUE;
                                case '2':
                                        break;
                                default:
                                        fprintf (stderr, "HTTP request failed: %s",
                                                sptr+1); /* '\n' is included */
                                        exit (1);
                        }
                }
                do {
                        readstring (request, linelength-1, myfile);
                        if (!strncmp(request, "Location:", 9))
                                strncpy (purl, request+10, 1023);
                } while (request[0] != '\r' && request[0] != '\n');
        } while (relocate && purl[0] && numrelocs++ < 5);
        if (relocate) {
                fprintf (stderr, "Too many HTTP relocations.\n");
                exit (1);
        }
        free (purl);
        free (request);
        return (myfile);
}

/* EOF */