annotate src/lib-program-client/program-client-remote.c @ 22346:bfe785a8ae62

lib-storage: Clarify keywords handling in mail_save_finish
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Thu, 29 Jun 2017 13:22:32 +0300
parents ba38c7002aa4
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20916
diff changeset
1 /* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
2 */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
3
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
4 #include "lib.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
5 #include "ioloop.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
6 #include "str.h"
22069
e6d9a30177c5 util: script: Amended the protocol to pass arguments escaped to prevent problems with newlines.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22066
diff changeset
7 #include "strescape.h"
22070
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
8 #include "array.h"
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
9 #include "net.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
10 #include "write-full.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
11 #include "eacces-error.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
12 #include "istream-private.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
13 #include "ostream.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
14
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
15 #include "program-client-private.h"
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
16
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
17 #include <unistd.h>
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
18 #include <sys/wait.h>
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
19 #include <sysexits.h>
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
20
22071
ba38c7002aa4 util: script: Increased the major protocol version due to earlier changes.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22070
diff changeset
21 #define PROGRAM_CLIENT_VERSION_MAJOR "4"
20904
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
22 #define PROGRAM_CLIENT_VERSION_MINOR "0"
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
23
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
24 #define PROGRAM_CLIENT_VERSION_STRING "VERSION\tscript\t" \
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
25 PROGRAM_CLIENT_VERSION_MAJOR "\t" \
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
26 PROGRAM_CLIENT_VERSION_MINOR "\n"
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
27
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
28 /*
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
29 * Script client input stream
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
30 */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
31
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
32 struct program_client_istream {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
33 struct istream_private istream;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
34
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
35 struct stat statbuf;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
36
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
37 struct program_client *client;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
38 };
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
39
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
40 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
41 void program_client_istream_destroy(struct iostream_private *stream)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
42 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
43 struct program_client_istream *scstream =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
44 (struct program_client_istream *) stream;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
45
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
46 i_stream_unref(&scstream->istream.parent);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
47 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
48
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
49 static ssize_t
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
50 program_client_istream_read(struct istream_private *stream)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
51 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
52 struct program_client_istream *scstream =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
53 (struct program_client_istream *) stream;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
54 size_t pos, reserved;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
55 ssize_t ret = 0;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
56
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
57 i_stream_skip(stream->parent, stream->skip);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
58 stream->skip = 0;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
59
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
60 stream->buffer = i_stream_get_data(stream->parent, &pos);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
61
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
62 reserved = 0;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
63 if (stream->buffer != NULL && pos >= 1) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
64 /* retain/hide potential return code at end of buffer */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
65 reserved = (stream->buffer[pos - 1] == '\n' && pos > 1 ? 2 : 1);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
66 pos -= reserved;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
67 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
68
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
69 if (stream->parent->eof) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
70 if (pos == 0)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
71 i_stream_skip(stream->parent, reserved);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
72 stream->istream.eof = TRUE;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
73 ret = -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
74 } else
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
75 do {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
76 if ((ret = i_stream_read(stream->parent)) == -2) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
77 return -2; /* input buffer full */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
78 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
79
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
80 if (ret == 0 || (ret < 0 && !stream->parent->eof))
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
81 break;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
82
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
83 stream->istream.stream_errno =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
84 stream->parent->stream_errno;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
85 stream->buffer =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
86 i_stream_get_data(stream->parent, &pos);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
87
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
88 if (stream->parent->eof) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
89 /* Check return code at EOF */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
90 if (stream->buffer != NULL && pos >= 2 &&
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
91 stream->buffer[pos - 1] == '\n') {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
92 switch (stream->buffer[pos - 2]) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
93 case '+':
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
94 scstream->client->exit_code = 1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
95 break;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
96 case '-':
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
97 scstream->client->exit_code = 0;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
98 break;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
99 default:
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
100 scstream->client->exit_code =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
101 -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
102 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
103 } else {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
104 scstream->client->exit_code = -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
105 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
106 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
107
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
108 if (stream->buffer != NULL && pos >= 1) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
109 /* retain/hide potential return code at end of buffer */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
110 size_t old_reserved = reserved;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
111 ssize_t reserve_mod;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
112
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
113 reserved = (stream->buffer[pos - 1] == '\n' &&
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
114 pos > 1 ? 2 : 1);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
115 reserve_mod = reserved - old_reserved;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
116 pos -= reserved;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
117
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
118 if (ret >= reserve_mod) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
119 ret -= reserve_mod;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
120 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
121 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
122
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
123 if (ret <= 0 && stream->parent->eof) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
124 /* Parent EOF and not more data to return; EOF here as well */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
125 if (pos == 0)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
126 i_stream_skip(stream->parent, reserved);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
127 stream->istream.eof = TRUE;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
128 ret = -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
129 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
130 } while (ret == 0);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
131
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
132 stream->pos = pos;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
133
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
134 i_assert(ret != -1 || stream->istream.eof ||
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
135 stream->istream.stream_errno != 0);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
136 return ret;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
137 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
138
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
139 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
140 void ATTR_NORETURN program_client_istream_sync(struct istream_private *stream ATTR_UNUSED)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
141 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
142 i_panic("program_client_istream sync() not implemented");
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
143 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
144
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
145 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
146 int program_client_istream_stat(struct istream_private *stream, bool exact)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
147 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
148 struct program_client_istream *scstream =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
149 (struct program_client_istream *) stream;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
150 const struct stat *st;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
151 int ret;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
152
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
153 /* Stat the original stream */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
154 ret = i_stream_stat(stream->parent, exact, &st);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
155 if (ret < 0 || st->st_size == -1 || !exact)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
156 return ret;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
157
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
158 scstream->statbuf = *st;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
159 scstream->statbuf.st_size = -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
160
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
161 return ret;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
162 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
163
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
164 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
165 struct istream *program_client_istream_create(struct program_client *program_client,
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
166 struct istream *input)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
167 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
168 struct program_client_istream *scstream;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
169
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
170 scstream = i_new(struct program_client_istream, 1);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
171 scstream->client = program_client;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
172
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
173 scstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
174
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
175 scstream->istream.iostream.destroy = program_client_istream_destroy;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
176 scstream->istream.read = program_client_istream_read;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
177 scstream->istream.sync = program_client_istream_sync;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
178 scstream->istream.stat = program_client_istream_stat;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
179
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
180 scstream->istream.istream.readable_fd = FALSE;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
181 scstream->istream.istream.blocking = input->blocking;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
182 scstream->istream.istream.seekable = FALSE;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
183
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
184 i_stream_seek(input, 0);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
185
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
186 return i_stream_create(&scstream->istream, input, -1);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
187 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
188
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
189 /*
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
190 * Program client
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
191 */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
192
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
193 struct program_client_remote {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
194 struct program_client client;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
195
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
196 bool noreply:1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
197 };
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
198
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
199 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
200 void program_client_remote_connected(struct program_client *pclient)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
201 {
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
202 struct program_client_remote *prclient =
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
203 (struct program_client_remote *) pclient;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
204 const char **args = pclient->args;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
205 string_t *str;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
206
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
207 io_remove(&pclient->io);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
208 program_client_init_streams(pclient);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
209
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
210 if (!prclient->noreply) {
20787
11ea2902f99d lib-program-client: Expose asynchronous API
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20785
diff changeset
211 struct istream *is = pclient->program_input;
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
212 pclient->program_input =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
213 program_client_istream_create(pclient, pclient->program_input);
20787
11ea2902f99d lib-program-client: Expose asynchronous API
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20785
diff changeset
214 i_stream_unref(&is);
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
215 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
216
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
217 str = t_str_new(1024);
20904
17e4d1a60dd0 lib-program-client: Move version string to define
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20903
diff changeset
218 str_append(str, PROGRAM_CLIENT_VERSION_STRING);
22070
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
219 if (array_is_created(&pclient->envs)) {
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
220 const char *const *env;
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
221 array_foreach(&pclient->envs, env) {
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
222 str_append(str, "env_");
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
223 str_append_tabescaped(str, *env);
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
224 str_append_c(str, '\n');
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
225 }
ded950b2b5d2 util: script: Amended protocol with the ability to convey a set of environment variables that are passed to the script.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22069
diff changeset
226 }
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
227 if (prclient->noreply)
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
228 str_append(str, "noreply\n");
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
229 else
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
230 str_append(str, "-\n");
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
231 if (args != NULL) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
232 for(; *args != NULL; args++) {
22069
e6d9a30177c5 util: script: Amended the protocol to pass arguments escaped to prevent problems with newlines.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 22066
diff changeset
233 str_append_tabescaped(str, *args);
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
234 str_append_c(str, '\n');
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
235 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
236 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
237 str_append_c(str, '\n');
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
238
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
239 if (o_stream_send(pclient->program_output,
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
240 str_data(str), str_len(str)) < 0) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
241 i_error("write(%s) failed: %s",
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
242 o_stream_get_name(pclient->program_output),
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
243 o_stream_get_error(pclient->program_output));
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
244 program_client_fail(pclient, PROGRAM_CLIENT_ERROR_IO);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
245 return;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
246 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
247
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
248 (void)program_client_connected(pclient);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
249 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
250
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
251 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
252 int program_client_remote_connect(struct program_client *pclient)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
253 {
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
254 struct program_client_remote *prclient =
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
255 (struct program_client_remote *) pclient;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
256 int fd;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
257
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
258 if ((fd = net_connect_unix_with_retries(pclient->path, 1000)) < 0) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
259 switch (errno) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
260 case EACCES:
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
261 i_error("%s",
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
262 eacces_error_get("net_connect_unix",
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
263 pclient->path));
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
264 return -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
265 default:
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
266 i_error("net_connect_unix(%s) failed: %m",
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
267 pclient->path);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
268 return -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
269 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
270 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
271
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
272 net_set_nonblock(fd, TRUE);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
273
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
274 pclient->fd_in = (prclient->noreply && pclient->output == NULL &&
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
275 !pclient->output_seekable ? -1 : fd);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
276 pclient->fd_out = fd;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
277 pclient->io =
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
278 io_add(fd, IO_WRITE, program_client_remote_connected, pclient);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
279 return 0;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
280 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
281
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
282 static
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
283 int program_client_remote_close_output(struct program_client *pclient)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
284 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
285 int fd_out = pclient->fd_out, fd_in = pclient->fd_in;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
286
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
287 pclient->fd_out = -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
288
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
289 /* Shutdown output; program stdin will get EOF */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
290 if (fd_out >= 0) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
291 if (fd_in >= 0) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
292 if (shutdown(fd_out, SHUT_WR) < 0 && errno != ENOTCONN) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
293 i_error("shutdown(%s, SHUT_WR) failed: %m",
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
294 pclient->path);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
295 return -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
296 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
297 } else if (close(fd_out) < 0) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
298 i_error("close(%s) failed: %m", pclient->path);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
299 return -1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
300 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
301 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
302
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
303 return 1;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
304 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
305
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
306 static
20900
61bebf0b543b lib-program-client: Disconnect asynchronously
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20787
diff changeset
307 void program_client_remote_disconnect(struct program_client *pclient, bool force)
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
308 {
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
309 struct program_client_remote *prclient =
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
310 (struct program_client_remote *)pclient;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
311
22066
50c94126d7ee lib-program-client: Gave variables pointing to a program-client more logical names.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 21390
diff changeset
312 if (pclient->error == PROGRAM_CLIENT_ERROR_NONE && !prclient->noreply &&
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
313 pclient->program_input != NULL && !force) {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
314 const unsigned char *data;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
315 size_t size;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
316
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
317 /* Skip any remaining program output and parse the exit code */
20916
ed7aa8beb34b lib-program-client: Correctly handle error code
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20904
diff changeset
318 while (i_stream_read_more
ed7aa8beb34b lib-program-client: Correctly handle error code
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20904
diff changeset
319 (pclient->program_input, &data, &size) > 0) {
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
320 i_stream_skip(pclient->program_input, size);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
321 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
322
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
323 /* Get exit code */
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
324 if (!pclient->program_input->eof)
20900
61bebf0b543b lib-program-client: Disconnect asynchronously
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20787
diff changeset
325 pclient->exit_code = -1;
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
326 } else {
20900
61bebf0b543b lib-program-client: Disconnect asynchronously
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20787
diff changeset
327 pclient->exit_code = 1;
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
328 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
329
20900
61bebf0b543b lib-program-client: Disconnect asynchronously
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20787
diff changeset
330 program_client_disconnected(pclient);
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
331 }
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
332
20903
d9208e0f8b08 lib-program-client: Add switch_ioloop vfunc
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20900
diff changeset
333 static
d9208e0f8b08 lib-program-client: Add switch_ioloop vfunc
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20900
diff changeset
334 void program_client_remote_switch_ioloop(struct program_client *pclient ATTR_UNUSED)
d9208e0f8b08 lib-program-client: Add switch_ioloop vfunc
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20900
diff changeset
335 {
d9208e0f8b08 lib-program-client: Add switch_ioloop vfunc
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20900
diff changeset
336 }
d9208e0f8b08 lib-program-client: Add switch_ioloop vfunc
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20900
diff changeset
337
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
338 struct program_client *
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
339 program_client_remote_create(const char *socket_path, const char *const *args,
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
340 const struct program_client_settings *set,
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
341 bool noreply)
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
342 {
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
343 struct program_client_remote *pclient;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
344 pool_t pool;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
345
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
346 pool = pool_alloconly_create("program client remote", 1024);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
347 pclient = p_new(pool, struct program_client_remote, 1);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
348 program_client_init(&pclient->client, pool, socket_path, args, set);
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
349 pclient->client.connect = program_client_remote_connect;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
350 pclient->client.close_output = program_client_remote_close_output;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
351 pclient->client.disconnect = program_client_remote_disconnect;
20903
d9208e0f8b08 lib-program-client: Add switch_ioloop vfunc
Aki Tuomi <aki.tuomi@dovecot.fi>
parents: 20900
diff changeset
352 pclient->client.switch_ioloop = program_client_remote_switch_ioloop;
20785
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
353 pclient->noreply = noreply;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
354
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
355 return &pclient->client;
3c8e6a9835d8 lib-program-client: Add program-client from pigeonhole
Aki Tuomi <aki.tuomi@dovecot.fi>
parents:
diff changeset
356 }