#include "cups.h"
#include "ipp.h"
#include "language.h"
#include "string.h"
#include "debug.h"
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#if defined(WIN32) || defined(__EMX__)
# include <io.h>
#else
# include <unistd.h>
#endif
http_status_t
cupsGetFd(http_t *http,
const char *resource,
int fd)
{
int bytes;
char buffer[8192];
http_status_t status;
DEBUG_printf(("cupsGetFd(http=%p, resource=\"%s\", fd=%d)\n", http,
resource, fd));
if (!http || !resource || fd < 0)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
do
{
httpClearFields(http);
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
if (httpGet(http, resource))
{
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
else
{
status = HTTP_UNAUTHORIZED;
continue;
}
}
while ((status = httpUpdate(http)) == HTTP_CONTINUE);
if (status == HTTP_UNAUTHORIZED)
{
httpFlush(http);
if (cupsDoAuthentication(http, "GET", resource))
break;
httpReconnect(http);
continue;
}
#ifdef HAVE_LIBSSL
else if (status == HTTP_UPGRADE_REQUIRED)
{
httpFlush(http);
httpReconnect(http);
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
continue;
}
#endif
}
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
if (status == HTTP_OK)
{
while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
write(fd, buffer, bytes);
}
else
httpFlush(http);
return (status);
}
http_status_t
cupsGetFile(http_t *http,
const char *resource,
const char *filename)
{
int fd;
http_status_t status;
if (!http || !resource || !filename)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
if ((fd = open(filename, O_WRONLY | O_EXCL | O_TRUNC)) < 0)
{
http->error = errno;
return (HTTP_ERROR);
}
status = cupsGetFd(http, resource, fd);
close(fd);
if (status != HTTP_OK)
unlink(filename);
return (status);
}
http_status_t
cupsPutFd(http_t *http,
const char *resource,
int fd)
{
int bytes;
char buffer[8192];
http_status_t status;
DEBUG_printf(("cupsPutFd(http=%p, resource=\"%s\", fd=%d)\n", http,
resource, fd));
if (!http || !resource || fd < 0)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
do
{
DEBUG_printf(("cupsPutFd: starting attempt, authstring=\"%s\"...\n",
http->authstring));
httpClearFields(http);
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
httpSetField(http, HTTP_FIELD_TRANSFER_ENCODING, "chunked");
if (httpPut(http, resource))
{
if (httpReconnect(http))
{
status = HTTP_ERROR;
break;
}
else
{
status = HTTP_UNAUTHORIZED;
continue;
}
}
lseek(fd, 0, SEEK_SET);
status = HTTP_CONTINUE;
while ((bytes = read(fd, buffer, sizeof(buffer))) > 0)
if (httpCheck(http))
{
if ((status = httpUpdate(http)) != HTTP_CONTINUE)
break;
}
else
httpWrite(http, buffer, bytes);
if (status == HTTP_CONTINUE)
{
httpWrite(http, buffer, 0);
while ((status = httpUpdate(http)) == HTTP_CONTINUE);
}
DEBUG_printf(("cupsPutFd: status=%d\n", status));
if (status == HTTP_UNAUTHORIZED)
{
httpFlush(http);
if (cupsDoAuthentication(http, "PUT", resource))
break;
httpReconnect(http);
continue;
}
#ifdef HAVE_LIBSSL
else if (status == HTTP_UPGRADE_REQUIRED)
{
httpFlush(http);
httpReconnect(http);
httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
continue;
}
#endif
}
while (status == HTTP_UNAUTHORIZED || status == HTTP_UPGRADE_REQUIRED);
if (status != HTTP_CREATED)
httpFlush(http);
return (status);
}
http_status_t
cupsPutFile(http_t *http,
const char *resource,
const char *filename)
{
int fd;
http_status_t status;
if (!http || !resource || !filename)
{
if (http)
http->error = EINVAL;
return (HTTP_ERROR);
}
if ((fd = open(filename, O_RDONLY)) < 0)
{
http->error = errno;
return (HTTP_ERROR);
}
status = cupsPutFd(http, resource, fd);
close(fd);
return (status);
}