File: clientlib.c

package info (click to toggle)
inn2 2.5.2-2~squeeze1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 11,072 kB
  • ctags: 8,521
  • sloc: ansic: 91,418; sh: 13,249; perl: 12,311; makefile: 2,928; yacc: 868; python: 342; lex: 266
file content (158 lines) | stat: -rw-r--r-- 3,385 bytes parent folder | download | duplicates (3)
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*  $Id: clientlib.c 8921 2010-01-22 23:33:08Z iulius $
**
**  Routines compatible with the NNTP "clientlib" routines.
*/
#include "config.h"
#include "clibrary.h"

#include "inn/innconf.h"
#include "inn/libinn.h"
#include "inn/nntp.h"


FILE	*ser_rd_fp = NULL;
FILE	*ser_wr_fp = NULL;
char	ser_line[NNTP_MAXLEN_COMMAND + 2];


/*
**  Get the name of the NNTP server.  Ignore the filename; we use
**  our own configuration stuff.  Return pointer to static data.
*/
char *
getserverbyfile(char *file UNUSED)
{
    static char	buff[256];

    strlcpy(buff, innconf->server, sizeof(buff));
    return buff;
}


/*
**  Get a connection to the remote news server.  Return server's reply
**  code or -1 on error.
*/
int
server_init(char *host, int port)
{
    char	line2[NNTP_MAXLEN_COMMAND];

    /* This interface may be used by clients that assume C News behavior and
       won't read inn.conf themselves. */
    if (innconf == NULL)
        if (!innconf_read(NULL))
            return -1;

    if (NNTPconnect(host, port, &ser_rd_fp, &ser_wr_fp, ser_line,
                    sizeof(ser_line)) < 0) {
	if (ser_line[0] == '\0')
	    /* I/O problem. */
	    return -1;

	/* Server rejected connection; return it's reply code. */
	return atoi(ser_line);
    }

    /* Send the INN command; if understood, use that reply. */
    put_server("MODE READER");
    if (get_server(line2, (int)sizeof line2) < 0)
	return -1;
    if (atoi(line2) != NNTP_ERR_COMMAND)
	strlcpy(ser_line, line2, sizeof(ser_line));

    /* Connected; return server's reply code. */
    return atoi(ser_line);
}


#define CANTPOST	\
    "NOTE:  This machine does not have permission to post articles"
#define CANTUSE		\
	"This machine does not have permission to use the %s news server.\n"
/*
**  Print a message based on the the server's initial response.
**  Return -1 if server wants us to go away.
*/
int
handle_server_response(int response, char *host)
{
    char	*p;

    switch (response) {
    default:
	printf("Unknown response code %d from %s.\n", response, host);
	return -1;
     case NNTP_FAIL_TERMINATING:
	if (atoi(ser_line) == response) {
	    p = &ser_line[strlen(ser_line) - 1];
	    if (*p == '\n' && *--p == '\r')
		*p = '\0';
	    if (p > &ser_line[3]) {
		printf("News server %s unavailable: %s\n", host,
			&ser_line[4]);
		return -1;
	    }
	}
	printf("News server %s unavailable, try later.\n", host);
	return -1;
    case NNTP_ERR_ACCESS:
	printf(CANTUSE, host);
	return -1;
    case NNTP_OK_BANNER_NOPOST:
	printf("%s.\n", CANTPOST);
	/* FALLTHROUGH */
    case NNTP_OK_BANNER_POST:
	break;
    }
    return 0;
}


/*
**  Send a line of text to the server.
*/
void
put_server(const char *buff)
{
    fprintf(ser_wr_fp, "%s\r\n", buff);
    fflush(ser_wr_fp);
}


/*
**  Get a line of text from the server, strip trailing \r\n.
**  Return -1 on error.
*/
int
get_server(char *buff, int buffsize)
{
    char	*p;

    if (fgets(buff, buffsize, ser_rd_fp) == NULL)
	return -1;
    p = &buff[strlen(buff)];
    if (p >= &buff[2] && p[-2] == '\r' && p[-1] == '\n')
	p[-2] = '\0';
    return 0;
}


/*
**  Send QUIT and close the server.
*/
void
close_server(void)
{
    char	buff[NNTP_MAXLEN_COMMAND];

    if (ser_wr_fp != NULL && ser_rd_fp != NULL) {
	put_server("QUIT");
	fclose(ser_wr_fp);
	ser_wr_fp = NULL;

	get_server(buff, (int)sizeof buff);
	fclose(ser_rd_fp);
	ser_rd_fp = NULL;
    }
}