forked from cfengine/core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprotocol.h
157 lines (144 loc) · 5.89 KB
/
protocol.h
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
/*
Copyright 2024 Northern.tech AS
This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; version 3.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
To the extent this program is licensed as part of the Enterprise
versions of CFEngine, the applicable Commercial Open Source License
(COSL) may apply to this file if you as a licensee so wish it. See
included file COSL.txt.
*/
#ifndef CFENGINE_PROTOCOL_H
#define CFENGINE_PROTOCOL_H
#include <cfnet.h>
#include <sequence.h>
#include <protocol_version.h> // ProtocolVersion
/**
* Receives a directory listing from a remote host.
*
* The server will use "/var/cfengine" as working directory if absolute path
* is not specified. The server sends the directory entries as a string
* separated by NUL-bytes, and ending with the magic string CFD_TERMINATOR.
*
* The function shall fail if connection is not established, or if the server
* gives a bad response (denoted by a message preceded by "BAD").
*
* @param [in] conn The connection to use
* @param [in] path Path on remote host
* @return A sequence of filenames in the requested directory on success, NULL
* on failure.
*
* Example (for printing each directory entry):
* @code
* AgentConnection *conn = ServerConnection("127.0.0.1", "666", ...);
* Seq *dir = ProtocolOpenDir(conn, "masterfiles");
* for (int i = 0; i < SeqLength(dir); i++)
* {
* char *entry = SeqAt(i);
* printf("%s\n", entry);
* }
* @endcode
*
* In the protocol, this will look like this on the server side:
* Received: OPENDIR masterfiles
* Translated to: OPENDIR /var/cfengine/masterfiles
* Sends string:
* ".\0..\0cfe_internal\0cf_promises_release_id\0...
* ...templates\0update.cf\0" CFD_TERMINATOR
*/
Seq *ProtocolOpenDir(AgentConnection *conn, const char *path);
/**
* Receives a file from a remote host.
*
* The server will use "/var/cfengine" as working directory if absolute path
* is not specified. The client will send a request that looks like this:
* `GET <buf_size> <remote_path>`
*
* `buf_size` is the local buffer size: how much of the file to receive in
* each transaction. It should be aligned to block size (which is usually
* 4096), but currently the protocol only allows _exactly_ 4095 bytes per
* transaction.
*
* The function shall fail if connection is not established, or if the server
* gives a bad response (denoted by a message preceded by "BAD").
*
* @param [in] conn The connection to use
* @param [in] remote_path Path on remote host
* @param [in] local_path Path of received file
* @param [in] file_size Size of file to get
* @param [in] perms Permissions of local file
* @return True if file was successfully transferred, false otherwise
*
* Example (for printing each directory entry):
* @code
* AgentConnection *conn = ServerConnection("127.0.0.1", "666", ...);
* bool got_file = ProtocolGet(conn, "masterfiles/update.cf",
* "update.cf", CF_MSGSIZE, 0644);
* if (got_file)
* {
* struct stat sb;
* stat("update.cf", &sb);
* printf("This file is %ld big!\n", sb.st_size);
* }
* @endcode
*
* In the protocol, this will look like this on the server side:
* Received: GET masterfiles/update.cf
* Translated to: GET /var/cfengine/masterfiles/update.cf
*/
bool ProtocolGet(AgentConnection *conn, const char *remote_path,
const char *local_path, const uint32_t file_size, int perms);
/**
* Receives a file from a remote host, see documentation for #ProtocolGet
*
* This funtion will first stat the remote path before attempting to receive
* it.
*/
bool ProtocolStatGet(AgentConnection *conn, const char *remote_path,
const char *local_path, int perms);
/**
* Receives statistics about a remote file.
*
* This is a cacheless version of #cf_remote_stat from stat_cache.c. This
* only supports sending with the latest cfnet protocol.
*
* When the `STAT` request is sent, it is sent together with the current time
* since the Epoch given by the `time` syscall denoted by `SYNCH <tloc>`. If
* the server is set to deny bad clocks (which is default), it will reject
* `STAT` requests from hosts where the clocks differ too much.
*
* When the server accepts the `STAT` request, it will send each field of the
* `Stat` struct from `stat_cache.h` as numbers delimited by spaces in a
* single string. Since the `Stat` struct is not cached, its fields are
* transferred to the \p stat_buf parameter.
*
* Example
* @code
* AgentConnection *conn = ServerConnection("127.0.0.1", "666", ...);
* struct stat stat_buf;
* ProtocolStat(conn, "masterfiles/update.cf", &stat_buf);
* assert((stat_buf.st_mode & S_IFMT) == S_IFREG);
* @endcode
*
* This is how the above example looks on the server side:
* Received: SYNCH 12356789 STAT masterfiles/update.cf
* Translated to: STAT /var/cfengine/masterfiles/update.cf
* Sends string:
* "OK: 0 33188 0 ..." etc.
*
* @param [in] conn The connection to use
* @param [in] remote_path Path on remote host
* @param [out] stat_buf Where to store statistics
* @return true on success, false on failure.
*/
bool ProtocolStat(AgentConnection *conn, const char *remote_path,
struct stat *stat_buf);
#endif