Ah.
Struct inaddr is defined after its first usage so move that definition up.
Done. Now it compiles
But the next problem is:
Code: Select all
D:\PRIVAT\ZX81\DEV\LAN\ZeddyNet\z88dk\libhttp>zcc +zx81 -I./include -O2 -preserv
e -vn addFormData.c freeFormData.c parseURI.c parseProto.c allocURI.c freeURI.c
base64enc.c request.c readData.c postsize.c getheader.c freeheaders.c readHeader
s.c htrecv.c
sccz80:"request.c" L:62 Error:Unknown symbol: sockaddr_in
sccz80:"request.c" L:63 Error:Unknown symbol: sockaddr_in
"sockaddr_in" is defined in "socket.h":
Code: Select all
#ifndef __SOCKET_H__
#define __SOCKET_H__
/*
* socket.h
*
* Routines that call the Spectranet ROM socket library.
*
* 2008-05-03 Dylan Smith
*/
/* Definitions */
#define AF_INET 0
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_RAW 3
/* Much of this should ultimately end up in sys/types.h */
#define in_addr_t unsigned long
/* Structures */
/* Moved up on 07-08-2018 after a hint of DOM */
struct in_addr
{
in_addr_t s_addr; /* 32 bits */
};
#define sockaddr sockaddr_in
#define socklen_t int
/* As defined in http://tools.ietf.org/html/draft-ietf-sip-bsd-systems-00 */
/* internet socket address structure */
struct sockaddr_in
{
int sin_family; /* offset 0 */
unsigned int sin_port; /* offset 2 */
struct in_addr sin_addr; /* offset 4 */
char sin_zero[8]; /* offset 8 */
};
//struct in_addr
//{
// in_addr_t s_addr; /* 32 bits */
//};
//#define sockaddr sockaddr_in
//#define socklen_t int
/* CALLER and FASTCALL linkage calls */
extern int __LIB__ socket(int domain, int type, int protocol);
extern int __LIB__ __FASTCALL__ sockclose(int fd);
extern int __LIB__ bind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
extern int __LIB__ connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);
extern int __LIB__ send(int sockfd, void *buf, int len, int flags);
extern int __LIB__ recv(int sockfd, void *buf, int len, int flags);
extern int __LIB__ accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
extern int __LIB__ listen(int sockfd, int backlog);
/* CALLEE linkage calls */
extern int __LIB__ __CALLEE__ socket_callee(int domain, int type, int proto);
extern int __LIB__ __CALLEE__ bind_callee(int sockfd, struct sockaddr *my_addr, socklen_t addrlen);
extern int __LIB__ __CALLEE__ connect_callee(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);
extern int __LIB__ __CALLEE__ send_callee(int sockfd, void *buf, int len, int flags);
extern int __LIB__ __CALLEE__ sendto_callee(int sockfd, void *buf, int len, int flags, struct sockaddr *to, socklen_t tolen);
extern int __LIB__ __CALLEE__ recv_callee(int sockfd, void *buf, int len, int flags);
extern int __LIB__ __CALLEE__ recvfrom_callee(int sockfd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen);
extern int __LIB__ __CALLEE__ accept_callee(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
extern int __LIB__ __CALLEE__ listen_callee(int sockfd, int backlog);
/* Make CALLEE default */
#define socket(a,b,c) socket_callee(a,b,c)
#define bind(a,b,c) bind_callee(a,b,c)
#define connect(a,b,c) connect_callee(a,b,c)
#define send(a,b,c,d) send_callee(a,b,c,d)
#define sendto(a,b,c,d,e,f) sendto_callee(a,b,c,d,e,f)
#define recv(a,b,c,d) recv_callee(a,b,c,d)
#define recvfrom(a,b,c,d,e,f) recvfrom_callee(a,b,c,d,e,f)
#define accept(a,b,c) accept_callee(a,b,c)
#define listen(a,b) listen_callee(a,b)
/* htons is a no-op, since all the calls convert machine byte order to
* network byte order. The macro is provided for compatibility */
#define htons(a) (a)
#define ntohs(a) (a)
#endif
The line 62 of "request.c", where the error occurs, is
Code: Select all
if(connect(sockfd, &remoteaddr, sizeof(sockaddr_in)) < 0)
{
sockclose(sockfd);
return EHTTP_CONNFAIL;
}
Full source of "request.c":
Code: Select all
/*
* The MIT License
*
* Copyright (c) 2010 Dylan Smith
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include <http.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
static Formdata *formhead=NULL;
static Formdata *formtail=NULL;
static char headersread=0;
#define HDRBUFSZ 512
int request(int type, URI *uri)
{
int sockfd, bytes;
struct sockaddr_in remoteaddr;
struct hostent *he;
char *authstring;
char hdrbuf[HDRBUFSZ];
char csizebuf[8];
char tmpbuf[120];
Formdata *fptr;
headersread=0;
he=gethostbyname(uri->host);
if(!he) return EHTTP_DNSFAIL;
sockfd=socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) return EHTTP_SOCKFAIL;
/* TODO: implement arbitrary ports for http */
remoteaddr.sin_port=htons(80);
remoteaddr.sin_addr.s_addr=he->h_addr;
if(connect(sockfd, &remoteaddr, sizeof(sockaddr_in)) < 0)
{
sockclose(sockfd);
return EHTTP_CONNFAIL;
}
if(type == GET)
{
sprintf(hdrbuf, "GET %s HTTP/1.1\n\r", uri->location);
addStdHeaders(hdrbuf, uri, HDRBUFSZ);
strlcat(hdrbuf, LINE_END, HDRBUFSZ);
bytes=send(sockfd, hdrbuf, strlen(hdrbuf), 0);
if(bytes < 0)
return EHTTP_WRITEFAIL;
}
else
{
sprintf(hdrbuf, "POST %s HTTP/1.1\n\r", uri->location);
addStdHeaders(hdrbuf, uri, HDRBUFSZ);
/* make up the Content-Length header */
/* TODO: Proper addition of headers, not this hideous
* function */
strlcat(hdrbuf, CONTLEN_HDR, HDRBUFSZ);
strlcat(hdrbuf, ": ", HDRBUFSZ);
sprintf(csizebuf, "%d\n\r", postsize());
strlcat(hdrbuf, csizebuf, HDRBUFSZ);
strlcat(hdrbuf, CONTENT_HDR, HDRBUFSZ);
strlcat(hdrbuf, LINE_END, HDRBUFSZ);
/* send what we have now. The reason being is that
* POST headers can be rather long, with many options */
/* bytes=send(sockfd, hdrbuf, strlen(hdrbuf), 0);
if(bytes < 0)
return EHTTP_WRITEFAIL; */
/* now the form data */
fptr=formhead;
while(fptr)
{
/*
sprintf(hdrbuf, "%s=%s\n\r",
fptr->param,
fptr->data);
printf("SENDING: %s", hdrbuf);
bytes=send(sockfd, hdrbuf, strlen(hdrbuf), 0);
if(bytes < 0)
return EHTTP_WRITEFAIL;*/
if(fptr->next)
{
sprintf(tmpbuf, "%s=%s&",
fptr->param,
fptr->data);
}
else
{
sprintf(tmpbuf, "%s=%s\n\r",
fptr->param,
fptr->data);
}
strlcat(hdrbuf, tmpbuf, HDRBUFSZ);
fptr=fptr->next;
}
bytes=send(sockfd, hdrbuf, strlen(hdrbuf), 0);
if(bytes < 0)
return EHTTP_WRITEFAIL;
}
return sockfd;
}
int addStdHeaders(char *hdrbuf, URI *uri, int bufsz)
{
char *authstr, *auth64buf;
int authlen;
if(uri->user)
{
authlen=strlen(uri->user)+strlen(uri->passwd)+2;
authstr=(char *)malloc(authlen);
if(!authstr) return ENOMEM;
sprintf(authstr, "%s:%s", uri->user, uri->passwd);
auth64buf=(char *)malloc(authlen+(authlen/2));
if(!auth64buf) return ENOMEM;
base64enc(auth64buf, authstr, authlen-1);
strlcat(hdrbuf, AUTH_HDR, bufsz);
strlcat(hdrbuf, auth64buf, bufsz);
strlcat(hdrbuf, LINE_END, bufsz);
free(authstr);
free(auth64buf);
}
strlcat(hdrbuf, USER_AGENT, bufsz);
strlcat(hdrbuf, ACCEPT_HDR, bufsz);
strlcat(hdrbuf, "Host: ", bufsz);
strlcat(hdrbuf, uri->host, bufsz);
strlcat(hdrbuf, LINE_END, bufsz);
return 0;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org!
http://sdm.link/slashdot