1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
/* $Id: clientactive.c 6135 2003-01-19 01:15:40Z rra $
**
*/
#include "config.h"
#include "clibrary.h"
#include <errno.h>
#include "inn/innconf.h"
#include "libinn.h"
#include "nntp.h"
#include "paths.h"
static char *CApathname;
static FILE *CAfp;
/*
** Get a copy of the active file for a client host to use, locally or
** remotely.
*/
FILE *
CAopen(FILE *FromServer, FILE *ToServer)
{
char *path;
/* Use a local (or NFS-mounted) copy if available. Make sure we don't
* try to delete it when we close it. */
path = concatpath(innconf->pathdb, _PATH_CLIENTACTIVE);
CAfp = fopen(path, "r");
free(path);
if (CAfp != NULL) {
CApathname = NULL;
return CAfp;
}
/* Use the active file from the server */
return CAlistopen(FromServer, ToServer, (char *)NULL);
}
/*
** Internal library routine.
*/
FILE *
CA_listopen(char *pathname, FILE *FromServer, FILE *ToServer,
const char *request)
{
char buff[BUFSIZ];
char *p;
int oerrno;
FILE *F;
F = fopen(pathname, "w");
if (F == NULL)
return NULL;
/* Send a LIST command to and capture the output. */
if (request == NULL)
fprintf(ToServer, "list\r\n");
else
fprintf(ToServer, "list %s\r\n", request);
fflush(ToServer);
/* Get the server's reply to our command. */
if (fgets(buff, sizeof buff, FromServer) == NULL
|| strncmp(buff, NNTP_LIST_FOLLOWS, strlen(NNTP_LIST_FOLLOWS)) != 0) {
oerrno = errno;
/* Only call CAclose() if opened through CAopen() */
if (strcmp(CApathname, pathname) == 0)
CAclose();
errno = oerrno;
return NULL;
}
/* Slurp up the rest of the response. */
while (fgets(buff, sizeof buff, FromServer) != NULL) {
if ((p = strchr(buff, '\r')) != NULL)
*p = '\0';
if ((p = strchr(buff, '\n')) != NULL)
*p = '\0';
if (buff[0] == '.' && buff[1] == '\0') {
if (ferror(F) || fflush(F) == EOF || fclose(F) == EOF)
break;
return fopen(pathname, "r");
}
fprintf(F, "%s\n", buff);
}
/* Ran out of input before finding the terminator; quit. */
oerrno = errno;
fclose(F);
CAclose();
errno = oerrno;
return NULL;
}
/*
** Use the NNTP list command to get a file from a server. Default is
** the active file, otherwise ask for whatever is in the request param.
*/
FILE *
CAlistopen(FILE *FromServer, FILE *ToServer, const char *request)
{
int fd, oerrno;
/* Gotta talk to the server -- see if we can. */
if (FromServer == NULL || ToServer == NULL) {
errno = EBADF;
return NULL;
}
CApathname = concatpath(innconf->pathtmp, _PATH_TEMPACTIVE);
fd = mkstemp(CApathname);
if (fd < 0) {
oerrno = errno;
free(CApathname);
CApathname = 0;
errno = oerrno;
return NULL;
}
close(fd);
return CAfp = CA_listopen(CApathname, FromServer, ToServer, request);
}
/*
** Close the file opened by CAopen or CAlistopen.
*/
void
CAclose(void)
{
if (CAfp) {
fclose(CAfp);
CAfp = NULL;
}
if (CApathname != NULL) {
unlink(CApathname);
CApathname = NULL;
}
}
|