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