summaryrefslogtreecommitdiffstats
path: root/daemon/daemon.h
blob: 8ad7b7c7d182e1a6202c8e4aaf4ec301d0b6a310 (plain)
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* libguestfs - the guestfsd daemon
 * Copyright (C) 2009 Red Hat Inc.
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef GUESTFSD_DAEMON_H
#define GUESTFSD_DAEMON_H

#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <rpc/types.h>
#include <rpc/xdr.h>

#include "../src/guestfs_protocol.h"

/*-- in guestfsd.c --*/
extern int xwrite (int sock, const void *buf, size_t len);
extern int xread (int sock, void *buf, size_t len);

extern int add_string (char ***argv, int *size, int *alloc, const char *str);
extern int count_strings (char * const* const argv);
extern void sort_strings (char **argv, int len);
extern void free_strings (char **argv);
extern void free_stringslen (char **argv, int len);

extern int command (char **stdoutput, char **stderror, const char *name, ...);
extern int commandr (char **stdoutput, char **stderror, const char *name, ...);
extern int commandv (char **stdoutput, char **stderror,
		     char * const* const argv);
extern int commandrv (char **stdoutput, char **stderror,
		      char * const* const argv);

extern char **split_lines (char *str);

extern int shell_quote (char *out, int len, const char *in);

extern int verbose;

/*-- in proto.c --*/
extern int proc_nr;
extern int serial;

/*-- in mount.c --*/
extern int root_mounted;

/*-- in stubs.c (auto-generated) --*/
extern void dispatch_incoming_message (XDR *);
extern guestfs_lvm_int_pv_list *parse_command_line_pvs (void);
extern guestfs_lvm_int_vg_list *parse_command_line_vgs (void);
extern guestfs_lvm_int_lv_list *parse_command_line_lvs (void);

/*-- in proto.c --*/
extern void main_loop (int sock);

/* ordinary daemon functions use these to indicate errors */
extern void reply_with_error (const char *fs, ...)
  __attribute__((format (printf,1,2)));
extern void reply_with_perror (const char *fs, ...)
  __attribute__((format (printf,1,2)));

/* daemon functions that receive files (FileIn) should call
 * receive_file for each FileIn parameter.
 */
typedef int (*receive_cb) (void *opaque, const void *buf, int len);
extern int receive_file (receive_cb cb, void *opaque);

/* daemon functions that receive files (FileIn) can call this
 * to cancel incoming transfers (eg. if there is a local error),
 * but they MUST then call reply_with_error or reply_with_perror.
 */
extern void cancel_receive (void);

/* daemon functions that return files (FileOut) should call
 * reply, then send_file_* for each FileOut parameter.
 * Note max write size if GUESTFS_MAX_CHUNK_SIZE.
 */
extern int send_file_write (const void *buf, int len);
extern void send_file_end (int cancel);

/* only call this if there is a FileOut parameter */
extern void reply (xdrproc_t xdrp, char *ret);

/* Helper for functions that need a root filesystem mounted.
 * NB. Cannot be used for FileIn functions.
 */
#define NEED_ROOT(errcode)						\
  do {									\
    if (!root_mounted) {						\
      reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \
      return (errcode);							\
    }									\
  }									\
  while (0)

/* Helper for functions that need an argument ("path") that is absolute.
 * NB. Cannot be used for FileIn functions.
 */
#define ABS_PATH(path,errcode)						\
  do {									\
    if ((path)[0] != '/') {						\
      reply_with_error ("%s: path must start with a / character", __func__); \
      return (errcode);							\
    }									\
  } while (0)

/* Helper for functions that need an argument ("path") that is a device.
 * NB. Cannot be used for FileIn functions.
 */
#define IS_DEVICE(path,errcode)						\
  do {									\
    struct stat statbuf;						\
    if (strncmp ((path), "/dev/", 5) != 0) {				\
      reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \
      return (errcode);							\
    }									\
    if (stat ((path), &statbuf) == -1) {				\
      reply_with_perror ("%s: %s", __func__, (path));			\
      return (errcode);							\
    }									\
  } while (0)

/* Helper for functions which need either an absolute path in the
 * mounted filesystem, OR a /dev/ device which exists.
 * NB. Cannot be used for FileIn functions.
 */
#define NEED_ROOT_OR_IS_DEVICE(path,errcode) \
  do {									\
    if (strncmp ((path), "/dev/", 5) == 0)				\
      IS_DEVICE ((path),(errcode));					\
    else {								\
      NEED_ROOT ((errcode));						\
      ABS_PATH ((path),(errcode));					\
    }									\
  } while (0)

/* NB:
 * (1) You must match CHROOT_IN and CHROOT_OUT even along error paths.
 * (2) You must not change directory!  cwd must always be "/", otherwise
 *     we can't escape our own chroot.
 * (3) All paths specified must be absolute.
 * (4) CHROOT_OUT does not affect errno.
 */
#define CHROOT_IN chroot ("/sysroot");
#define CHROOT_OUT \
  do { int old_errno = errno; chroot ("."); errno = old_errno; } while (0)

/* Marks functions which are not implemented.
 * NB. Cannot be used for FileIn functions.
 */
#define XXX_NOT_IMPL(errcode)						\
  do {									\
    reply_with_error ("%s: function not implemented", __func__);	\
    return (errcode);							\
  }									\
  while (0)

#endif /* GUESTFSD_DAEMON_H */