зеркало из https://github.com/mozilla/gecko-dev.git
334 строки
5.9 KiB
C
334 строки
5.9 KiB
C
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Web Sniffer.
|
|
*
|
|
* The Initial Developer of the Original Code is Erik van der Poel.
|
|
* Portions created by Erik van der Poel are
|
|
* Copyright (C) 1998,1999,2000 Erik van der Poel.
|
|
* All Rights Reserved.
|
|
*
|
|
* Contributor(s): Bruce Robson
|
|
*/
|
|
|
|
#include "plat.h"
|
|
|
|
#include <errno.h>
|
|
#include <malloc.h>
|
|
#include <memory.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#ifdef PLAT_UNIX
|
|
#include <sys/stropts.h>
|
|
#else
|
|
#include <sys/socket.h>
|
|
#endif
|
|
|
|
#include "io.h"
|
|
#include "utils.h"
|
|
|
|
struct Input
|
|
{
|
|
unsigned long readAlloc;
|
|
const unsigned char *readBuf;
|
|
const unsigned char *readBufPtr;
|
|
const unsigned char *readBufEnd;
|
|
const unsigned char *readBufMarkBegin;
|
|
const unsigned char *readBufMarkEnd;
|
|
unsigned long streamSize;
|
|
};
|
|
|
|
static Input *
|
|
inputAlloc(void)
|
|
{
|
|
Input *input;
|
|
|
|
input = calloc(sizeof(Input), 1);
|
|
if (!input)
|
|
{
|
|
fprintf(stderr, "cannot calloc Input\n");
|
|
exit(0);
|
|
}
|
|
|
|
return input;
|
|
}
|
|
|
|
static Input *
|
|
readInit(void)
|
|
{
|
|
Input *input;
|
|
|
|
input = inputAlloc();
|
|
input->readAlloc = 1;
|
|
input->readBuf = calloc(input->readAlloc + 1, 1);
|
|
if (!input->readBuf)
|
|
{
|
|
fprintf(stderr, "cannot calloc readBuf\n");
|
|
exit(0);
|
|
}
|
|
|
|
return input;
|
|
}
|
|
|
|
Input *
|
|
readStream(int fd, unsigned char *url)
|
|
{
|
|
size_t bytesAvailable;
|
|
int bytesRead;
|
|
fd_set fdset;
|
|
Input *input;
|
|
int offset;
|
|
int ret;
|
|
struct stat statBuf;
|
|
unsigned long streamSize;
|
|
struct timeval timeout;
|
|
|
|
input = readInit();
|
|
|
|
FD_ZERO(&fdset);
|
|
FD_SET(fd, &fdset);
|
|
|
|
timeout.tv_sec = 5 * 60;
|
|
timeout.tv_usec = 0;
|
|
|
|
offset = 0;
|
|
streamSize = 0;
|
|
while (1)
|
|
{
|
|
ret = select(fd + 1, &fdset, NULL, NULL, &timeout);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "readStream: select timed out: %s\n",
|
|
url);
|
|
streamSize = 0;
|
|
break;
|
|
}
|
|
else if (ret == -1)
|
|
{
|
|
perror("select");
|
|
streamSize = 0;
|
|
break;
|
|
}
|
|
#ifdef PLAT_UNIX
|
|
if (ioctl(fd, I_NREAD, &bytesAvailable) == -1)
|
|
#else
|
|
if (ioctl(fd, FIONREAD, &bytesAvailable) == -1)
|
|
#endif
|
|
{
|
|
/* if fd is file, we get this error */
|
|
if (errno == ENOTTY)
|
|
{
|
|
if (fstat(fd, &statBuf))
|
|
{
|
|
perror("fstat");
|
|
streamSize = 0;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
bytesAvailable = statBuf.st_size;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (errno != ECONNRESET)
|
|
{
|
|
perror("ioctl");
|
|
}
|
|
streamSize = 0;
|
|
break;
|
|
}
|
|
}
|
|
if (offset + bytesAvailable > input->readAlloc)
|
|
{
|
|
input->readAlloc = offset + bytesAvailable;
|
|
input->readBuf = realloc((void *) input->readBuf,
|
|
input->readAlloc + 1);
|
|
if (!input->readBuf)
|
|
{
|
|
fprintf(stderr, "cannot realloc readBuf %ld\n",
|
|
input->readAlloc + 1);
|
|
streamSize = 0;
|
|
break;
|
|
}
|
|
}
|
|
bytesRead = read(fd, (void *) (input->readBuf + offset),
|
|
bytesAvailable);
|
|
if (bytesRead <= 0)
|
|
{
|
|
break;
|
|
}
|
|
else if (bytesRead > bytesAvailable)
|
|
{
|
|
/* should not happen */
|
|
streamSize = 0;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
offset += bytesRead;
|
|
streamSize += bytesRead;
|
|
}
|
|
}
|
|
|
|
((unsigned char *) input->readBuf)[streamSize] = 0;
|
|
|
|
input->readBufPtr = input->readBuf;
|
|
input->readBufEnd = input->readBuf + streamSize;
|
|
input->streamSize = streamSize;
|
|
input->readBufMarkEnd = input->readBuf;
|
|
|
|
return input;
|
|
}
|
|
|
|
Input *
|
|
readAvailableBytes(int fd)
|
|
{
|
|
int bytesRead;
|
|
Input *input;
|
|
|
|
input = inputAlloc();
|
|
input->readAlloc = 10240;
|
|
input->readBuf = calloc(input->readAlloc + 1, 1);
|
|
if (!input->readBuf)
|
|
{
|
|
fprintf(stderr, "cannot calloc readBuf\n");
|
|
exit(0);
|
|
}
|
|
input->readBufPtr = input->readBuf;
|
|
input->readBufEnd = input->readBuf;
|
|
input->readBufMarkEnd = input->readBuf;
|
|
bytesRead = read(fd, (void *) input->readBuf, input->readAlloc);
|
|
if (bytesRead < 0)
|
|
{
|
|
perror("read");
|
|
return input;
|
|
}
|
|
else if (bytesRead == input->readAlloc)
|
|
{
|
|
fprintf(stderr, "readBuf too small\n");
|
|
}
|
|
|
|
((unsigned char *) input->readBuf)[bytesRead] = 0;
|
|
|
|
input->readBufEnd = input->readBuf + bytesRead;
|
|
input->streamSize = bytesRead;
|
|
|
|
return input;
|
|
}
|
|
|
|
void
|
|
inputFree(Input *input)
|
|
{
|
|
free((char *) input->readBuf);
|
|
free(input);
|
|
}
|
|
|
|
unsigned short
|
|
getByte(Input *input)
|
|
{
|
|
if (input->readBufPtr >= input->readBufEnd)
|
|
{
|
|
input->readBufPtr++;
|
|
return 256;
|
|
}
|
|
|
|
return *input->readBufPtr++;
|
|
}
|
|
|
|
void
|
|
unGetByte(Input *input)
|
|
{
|
|
if (input->readBufPtr > input->readBuf)
|
|
{
|
|
input->readBufPtr--;
|
|
}
|
|
}
|
|
|
|
const unsigned char *
|
|
current(Input *input)
|
|
{
|
|
return input->readBufPtr;
|
|
}
|
|
|
|
void
|
|
set(Input *input, const unsigned char *pointer)
|
|
{
|
|
input->readBufPtr = (unsigned char *) pointer;
|
|
}
|
|
|
|
unsigned long
|
|
inputLength(Input *input)
|
|
{
|
|
return input->streamSize;
|
|
}
|
|
|
|
unsigned char *
|
|
copyMemory(Input *input, unsigned long *len)
|
|
{
|
|
unsigned char *ret;
|
|
|
|
*len = input->readBufMarkEnd - input->readBufMarkBegin;
|
|
ret = malloc(*len);
|
|
if (!ret)
|
|
{
|
|
fprintf(stderr, "cannot calloc block\n");
|
|
exit(0);
|
|
}
|
|
memcpy(ret, input->readBufMarkBegin, *len);
|
|
|
|
return ret;
|
|
}
|
|
|
|
unsigned char *
|
|
copy(Input *input)
|
|
{
|
|
return copySizedString(input->readBufMarkBegin,
|
|
input->readBufMarkEnd - input->readBufMarkBegin);
|
|
}
|
|
|
|
unsigned char *
|
|
copyLower(Input *input)
|
|
{
|
|
return lowerCase(copySizedString(input->readBufMarkBegin,
|
|
input->readBufMarkEnd - input->readBufMarkBegin));
|
|
}
|
|
|
|
unsigned short
|
|
trimTrailingWhiteSpace(Input *input)
|
|
{
|
|
unsigned char c;
|
|
|
|
input->readBufPtr -= 2;
|
|
do
|
|
{
|
|
c = *input->readBufPtr--;
|
|
} while
|
|
(
|
|
(c == ' ') ||
|
|
(c == '\t') ||
|
|
(c == '\r') ||
|
|
(c == '\n')
|
|
);
|
|
input->readBufPtr += 2;
|
|
|
|
return *input->readBufPtr++;
|
|
}
|
|
|
|
void
|
|
mark(Input *input, int offset)
|
|
{
|
|
input->readBufMarkBegin = input->readBufMarkEnd;
|
|
input->readBufMarkEnd = input->readBufPtr + offset;
|
|
}
|