xref: /qemu/hw/9pfs/virtio-9p.h (revision 541dc0d47f10973c241e9955afc2aefc96adec51)
19f107513SAnthony Liguori #ifndef _QEMU_VIRTIO_9P_H
29f107513SAnthony Liguori #define _QEMU_VIRTIO_9P_H
39f107513SAnthony Liguori 
49f107513SAnthony Liguori #include <sys/types.h>
59f107513SAnthony Liguori #include <dirent.h>
69f107513SAnthony Liguori #include <sys/time.h>
79f107513SAnthony Liguori #include <utime.h>
8ff06030fSVenkateswararao Jujjuri (JV) #include "hw/virtio.h"
9353ac78dSAneesh Kumar K.V #include "fsdev/file-op-9p.h"
109f107513SAnthony Liguori 
119f107513SAnthony Liguori /* The feature bitmap for virtio 9P */
129f107513SAnthony Liguori /* The mount point is specified in a config variable */
139f107513SAnthony Liguori #define VIRTIO_9P_MOUNT_TAG 0
149f107513SAnthony Liguori 
159f107513SAnthony Liguori enum {
168f4d1ca5SArun R Bharadwaj     P9_TLERROR = 6,
178f4d1ca5SArun R Bharadwaj     P9_RLERROR,
18be940c87SM. Mohan Kumar     P9_TSTATFS = 8,
19be940c87SM. Mohan Kumar     P9_RSTATFS,
20771e9d4cSM. Mohan Kumar     P9_TLOPEN = 12,
21771e9d4cSM. Mohan Kumar     P9_RLOPEN,
22c1568af5SVenkateswararao Jujjuri (JV)     P9_TLCREATE = 14,
23c1568af5SVenkateswararao Jujjuri (JV)     P9_RLCREATE,
2408c60fc9SVenkateswararao Jujjuri (JV)     P9_TSYMLINK = 16,
2508c60fc9SVenkateswararao Jujjuri (JV)     P9_RSYMLINK,
265268ceccSM. Mohan Kumar     P9_TMKNOD = 18,
275268ceccSM. Mohan Kumar     P9_RMKNOD,
28c7b4b0b3SM. Mohan Kumar     P9_TRENAME = 20,
29c7b4b0b3SM. Mohan Kumar     P9_RRENAME,
30df0973a4SM. Mohan Kumar     P9_TREADLINK = 22,
31df0973a4SM. Mohan Kumar     P9_RREADLINK,
3200ede4c2SSripathi Kodi     P9_TGETATTR = 24,
3300ede4c2SSripathi Kodi     P9_RGETATTR,
34c79ce737SSripathi Kodi     P9_TSETATTR = 26,
35c79ce737SSripathi Kodi     P9_RSETATTR,
36fa32ef88SAneesh Kumar K.V     P9_TXATTRWALK = 30,
37fa32ef88SAneesh Kumar K.V     P9_RXATTRWALK,
3810b468bdSAneesh Kumar K.V     P9_TXATTRCREATE = 32,
3910b468bdSAneesh Kumar K.V     P9_RXATTRCREATE,
40c18e2f94SSripathi Kodi     P9_TREADDIR = 40,
41c18e2f94SSripathi Kodi     P9_RREADDIR,
42b41e95d3SVenkateswararao Jujjuri (JV)     P9_TFSYNC = 50,
43b41e95d3SVenkateswararao Jujjuri (JV)     P9_RFSYNC,
4482cc3ee8SM. Mohan Kumar     P9_TLOCK = 52,
4582cc3ee8SM. Mohan Kumar     P9_RLOCK,
468f354003SM. Mohan Kumar     P9_TGETLOCK = 54,
478f354003SM. Mohan Kumar     P9_RGETLOCK,
48b2c224beSVenkateswararao Jujjuri (JV)     P9_TLINK = 70,
49b2c224beSVenkateswararao Jujjuri (JV)     P9_RLINK,
50b67592eaSM. Mohan Kumar     P9_TMKDIR = 72,
51b67592eaSM. Mohan Kumar     P9_RMKDIR,
529f107513SAnthony Liguori     P9_TVERSION = 100,
539f107513SAnthony Liguori     P9_RVERSION,
549f107513SAnthony Liguori     P9_TAUTH = 102,
559f107513SAnthony Liguori     P9_RAUTH,
569f107513SAnthony Liguori     P9_TATTACH = 104,
579f107513SAnthony Liguori     P9_RATTACH,
589f107513SAnthony Liguori     P9_TERROR = 106,
599f107513SAnthony Liguori     P9_RERROR,
609f107513SAnthony Liguori     P9_TFLUSH = 108,
619f107513SAnthony Liguori     P9_RFLUSH,
629f107513SAnthony Liguori     P9_TWALK = 110,
639f107513SAnthony Liguori     P9_RWALK,
649f107513SAnthony Liguori     P9_TOPEN = 112,
659f107513SAnthony Liguori     P9_ROPEN,
669f107513SAnthony Liguori     P9_TCREATE = 114,
679f107513SAnthony Liguori     P9_RCREATE,
689f107513SAnthony Liguori     P9_TREAD = 116,
699f107513SAnthony Liguori     P9_RREAD,
709f107513SAnthony Liguori     P9_TWRITE = 118,
719f107513SAnthony Liguori     P9_RWRITE,
729f107513SAnthony Liguori     P9_TCLUNK = 120,
739f107513SAnthony Liguori     P9_RCLUNK,
749f107513SAnthony Liguori     P9_TREMOVE = 122,
759f107513SAnthony Liguori     P9_RREMOVE,
769f107513SAnthony Liguori     P9_TSTAT = 124,
779f107513SAnthony Liguori     P9_RSTAT,
789f107513SAnthony Liguori     P9_TWSTAT = 126,
799f107513SAnthony Liguori     P9_RWSTAT,
809f107513SAnthony Liguori };
819f107513SAnthony Liguori 
829f107513SAnthony Liguori 
839f107513SAnthony Liguori /* qid.types */
849f107513SAnthony Liguori enum {
859f107513SAnthony Liguori     P9_QTDIR = 0x80,
869f107513SAnthony Liguori     P9_QTAPPEND = 0x40,
879f107513SAnthony Liguori     P9_QTEXCL = 0x20,
889f107513SAnthony Liguori     P9_QTMOUNT = 0x10,
899f107513SAnthony Liguori     P9_QTAUTH = 0x08,
909f107513SAnthony Liguori     P9_QTTMP = 0x04,
919f107513SAnthony Liguori     P9_QTSYMLINK = 0x02,
929f107513SAnthony Liguori     P9_QTLINK = 0x01,
939f107513SAnthony Liguori     P9_QTFILE = 0x00,
949f107513SAnthony Liguori };
959f107513SAnthony Liguori 
9684151514SM. Mohan Kumar enum p9_proto_version {
9784151514SM. Mohan Kumar     V9FS_PROTO_2000U = 0x01,
9884151514SM. Mohan Kumar     V9FS_PROTO_2000L = 0x02,
9984151514SM. Mohan Kumar };
10084151514SM. Mohan Kumar 
1019f107513SAnthony Liguori #define P9_NOTAG    (u16)(~0)
1029f107513SAnthony Liguori #define P9_NOFID    (u32)(~0)
1039f107513SAnthony Liguori #define P9_MAXWELEM 16
104faa44e3dSVenkateswararao Jujjuri (JV) static inline const char *rpath(FsContext *ctx, const char *path, char *buffer)
105faa44e3dSVenkateswararao Jujjuri (JV) {
106faa44e3dSVenkateswararao Jujjuri (JV)     snprintf(buffer, PATH_MAX, "%s/%s", ctx->fs_root, path);
107faa44e3dSVenkateswararao Jujjuri (JV)     return buffer;
108faa44e3dSVenkateswararao Jujjuri (JV) }
1099f107513SAnthony Liguori 
1105e94c103SM. Mohan Kumar /*
1115e94c103SM. Mohan Kumar  * ample room for Twrite/Rread header
1125e94c103SM. Mohan Kumar  * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4]
1135e94c103SM. Mohan Kumar  */
1145e94c103SM. Mohan Kumar #define P9_IOHDRSZ 24
1155e94c103SM. Mohan Kumar 
1169f107513SAnthony Liguori typedef struct V9fsPDU V9fsPDU;
117ff06030fSVenkateswararao Jujjuri (JV) struct V9fsState;
1189f107513SAnthony Liguori 
1199f107513SAnthony Liguori struct V9fsPDU
1209f107513SAnthony Liguori {
1219f107513SAnthony Liguori     uint32_t size;
1229f107513SAnthony Liguori     uint16_t tag;
1239f107513SAnthony Liguori     uint8_t id;
1249f107513SAnthony Liguori     VirtQueueElement elem;
125ff06030fSVenkateswararao Jujjuri (JV)     struct V9fsState *s;
1269f107513SAnthony Liguori     QLIST_ENTRY(V9fsPDU) next;
1279f107513SAnthony Liguori };
1289f107513SAnthony Liguori 
1299f107513SAnthony Liguori 
1309f107513SAnthony Liguori /* FIXME
1319f107513SAnthony Liguori  * 1) change user needs to set groups and stuff
1329f107513SAnthony Liguori  */
1339f107513SAnthony Liguori 
1349f107513SAnthony Liguori /* from Linux's linux/virtio_9p.h */
1359f107513SAnthony Liguori 
1369f107513SAnthony Liguori /* The ID for virtio console */
1379f107513SAnthony Liguori #define VIRTIO_ID_9P    9
1389f107513SAnthony Liguori #define MAX_REQ         128
1399f107513SAnthony Liguori #define MAX_TAG_LEN     32
1409f107513SAnthony Liguori 
1419f107513SAnthony Liguori #define BUG_ON(cond) assert(!(cond))
1429f107513SAnthony Liguori 
1439f107513SAnthony Liguori typedef struct V9fsFidState V9fsFidState;
1449f107513SAnthony Liguori 
1459f107513SAnthony Liguori typedef struct V9fsString
1469f107513SAnthony Liguori {
1479f107513SAnthony Liguori     int16_t size;
1489f107513SAnthony Liguori     char *data;
1499f107513SAnthony Liguori } V9fsString;
1509f107513SAnthony Liguori 
1519f107513SAnthony Liguori typedef struct V9fsQID
1529f107513SAnthony Liguori {
1539f107513SAnthony Liguori     int8_t type;
1549f107513SAnthony Liguori     int32_t version;
1559f107513SAnthony Liguori     int64_t path;
1569f107513SAnthony Liguori } V9fsQID;
1579f107513SAnthony Liguori 
1589f107513SAnthony Liguori typedef struct V9fsStat
1599f107513SAnthony Liguori {
1609f107513SAnthony Liguori     int16_t size;
1619f107513SAnthony Liguori     int16_t type;
1629f107513SAnthony Liguori     int32_t dev;
1639f107513SAnthony Liguori     V9fsQID qid;
1649f107513SAnthony Liguori     int32_t mode;
1659f107513SAnthony Liguori     int32_t atime;
1669f107513SAnthony Liguori     int32_t mtime;
1679f107513SAnthony Liguori     int64_t length;
1689f107513SAnthony Liguori     V9fsString name;
1699f107513SAnthony Liguori     V9fsString uid;
1709f107513SAnthony Liguori     V9fsString gid;
1719f107513SAnthony Liguori     V9fsString muid;
1729f107513SAnthony Liguori     /* 9p2000.u */
1739f107513SAnthony Liguori     V9fsString extension;
1749f107513SAnthony Liguori    int32_t n_uid;
1759f107513SAnthony Liguori     int32_t n_gid;
1769f107513SAnthony Liguori     int32_t n_muid;
1779f107513SAnthony Liguori } V9fsStat;
1789f107513SAnthony Liguori 
179d62dbb51SAneesh Kumar K.V enum {
180d62dbb51SAneesh Kumar K.V     P9_FID_NONE = 0,
181d62dbb51SAneesh Kumar K.V     P9_FID_FILE,
182d62dbb51SAneesh Kumar K.V     P9_FID_DIR,
183d62dbb51SAneesh Kumar K.V     P9_FID_XATTR,
184d62dbb51SAneesh Kumar K.V };
185d62dbb51SAneesh Kumar K.V 
186d62dbb51SAneesh Kumar K.V typedef struct V9fsXattr
187d62dbb51SAneesh Kumar K.V {
188d62dbb51SAneesh Kumar K.V     int64_t copied_len;
189d62dbb51SAneesh Kumar K.V     int64_t len;
190d62dbb51SAneesh Kumar K.V     void *value;
191d62dbb51SAneesh Kumar K.V     V9fsString name;
192d62dbb51SAneesh Kumar K.V     int flags;
193d62dbb51SAneesh Kumar K.V } V9fsXattr;
194d62dbb51SAneesh Kumar K.V 
1959f107513SAnthony Liguori struct V9fsFidState
1969f107513SAnthony Liguori {
197d62dbb51SAneesh Kumar K.V     int fid_type;
1989f107513SAnthony Liguori     int32_t fid;
1999f107513SAnthony Liguori     V9fsString path;
200d62dbb51SAneesh Kumar K.V     union {
2019f107513SAnthony Liguori 	int fd;
2029f107513SAnthony Liguori 	DIR *dir;
203d62dbb51SAneesh Kumar K.V 	V9fsXattr xattr;
204d62dbb51SAneesh Kumar K.V     } fs;
2059f107513SAnthony Liguori     uid_t uid;
2069f107513SAnthony Liguori     V9fsFidState *next;
2079f107513SAnthony Liguori };
2089f107513SAnthony Liguori 
2099f107513SAnthony Liguori typedef struct V9fsState
2109f107513SAnthony Liguori {
2119f107513SAnthony Liguori     VirtIODevice vdev;
2129f107513SAnthony Liguori     VirtQueue *vq;
2139f107513SAnthony Liguori     V9fsPDU pdus[MAX_REQ];
2149f107513SAnthony Liguori     QLIST_HEAD(, V9fsPDU) free_list;
2159f107513SAnthony Liguori     V9fsFidState *fid_list;
2169f107513SAnthony Liguori     FileOperations *ops;
2179f107513SAnthony Liguori     FsContext ctx;
2189f107513SAnthony Liguori     uint16_t tag_len;
2199f107513SAnthony Liguori     uint8_t *tag;
2209f107513SAnthony Liguori     size_t config_size;
22184151514SM. Mohan Kumar     enum p9_proto_version proto_version;
2225e94c103SM. Mohan Kumar     int32_t msize;
2239f107513SAnthony Liguori } V9fsState;
2249f107513SAnthony Liguori 
225fac4f111SVenkateswararao Jujjuri (JV) typedef struct V9fsStatState {
226fac4f111SVenkateswararao Jujjuri (JV)     V9fsPDU *pdu;
227fac4f111SVenkateswararao Jujjuri (JV)     size_t offset;
228fac4f111SVenkateswararao Jujjuri (JV)     V9fsStat v9stat;
229fac4f111SVenkateswararao Jujjuri (JV)     V9fsFidState *fidp;
230fac4f111SVenkateswararao Jujjuri (JV)     struct stat stbuf;
231fac4f111SVenkateswararao Jujjuri (JV) } V9fsStatState;
232fac4f111SVenkateswararao Jujjuri (JV) 
23300ede4c2SSripathi Kodi typedef struct V9fsStatDotl {
23400ede4c2SSripathi Kodi     uint64_t st_result_mask;
23500ede4c2SSripathi Kodi     V9fsQID qid;
23600ede4c2SSripathi Kodi     uint32_t st_mode;
23700ede4c2SSripathi Kodi     uint32_t st_uid;
23800ede4c2SSripathi Kodi     uint32_t st_gid;
23900ede4c2SSripathi Kodi     uint64_t st_nlink;
24000ede4c2SSripathi Kodi     uint64_t st_rdev;
24100ede4c2SSripathi Kodi     uint64_t st_size;
24200ede4c2SSripathi Kodi     uint64_t st_blksize;
24300ede4c2SSripathi Kodi     uint64_t st_blocks;
24400ede4c2SSripathi Kodi     uint64_t st_atime_sec;
24500ede4c2SSripathi Kodi     uint64_t st_atime_nsec;
24600ede4c2SSripathi Kodi     uint64_t st_mtime_sec;
24700ede4c2SSripathi Kodi     uint64_t st_mtime_nsec;
24800ede4c2SSripathi Kodi     uint64_t st_ctime_sec;
24900ede4c2SSripathi Kodi     uint64_t st_ctime_nsec;
25000ede4c2SSripathi Kodi     uint64_t st_btime_sec;
25100ede4c2SSripathi Kodi     uint64_t st_btime_nsec;
25200ede4c2SSripathi Kodi     uint64_t st_gen;
25300ede4c2SSripathi Kodi     uint64_t st_data_version;
25400ede4c2SSripathi Kodi } V9fsStatDotl;
25500ede4c2SSripathi Kodi 
256fac4f111SVenkateswararao Jujjuri (JV) typedef struct V9fsOpenState {
257fac4f111SVenkateswararao Jujjuri (JV)     V9fsPDU *pdu;
258fac4f111SVenkateswararao Jujjuri (JV)     size_t offset;
259771e9d4cSM. Mohan Kumar     int32_t mode;
260fac4f111SVenkateswararao Jujjuri (JV)     V9fsFidState *fidp;
261fac4f111SVenkateswararao Jujjuri (JV)     V9fsQID qid;
262fac4f111SVenkateswararao Jujjuri (JV)     struct stat stbuf;
2635e94c103SM. Mohan Kumar     int iounit;
264fac4f111SVenkateswararao Jujjuri (JV) } V9fsOpenState;
265fac4f111SVenkateswararao Jujjuri (JV) 
266fac4f111SVenkateswararao Jujjuri (JV) typedef struct V9fsReadState {
267fac4f111SVenkateswararao Jujjuri (JV)     V9fsPDU *pdu;
268fac4f111SVenkateswararao Jujjuri (JV)     size_t offset;
269fac4f111SVenkateswararao Jujjuri (JV)     int32_t count;
270fac4f111SVenkateswararao Jujjuri (JV)     int32_t total;
271fac4f111SVenkateswararao Jujjuri (JV)     int64_t off;
272fac4f111SVenkateswararao Jujjuri (JV)     V9fsFidState *fidp;
273fac4f111SVenkateswararao Jujjuri (JV)     struct iovec iov[128]; /* FIXME: bad, bad, bad */
274fac4f111SVenkateswararao Jujjuri (JV)     struct iovec *sg;
275fac4f111SVenkateswararao Jujjuri (JV)     off_t dir_pos;
276fac4f111SVenkateswararao Jujjuri (JV)     struct dirent *dent;
277fac4f111SVenkateswararao Jujjuri (JV)     struct stat stbuf;
278fac4f111SVenkateswararao Jujjuri (JV)     V9fsString name;
279fac4f111SVenkateswararao Jujjuri (JV)     V9fsStat v9stat;
280fac4f111SVenkateswararao Jujjuri (JV)     int32_t len;
281fac4f111SVenkateswararao Jujjuri (JV)     int32_t cnt;
282fac4f111SVenkateswararao Jujjuri (JV)     int32_t max_count;
283fac4f111SVenkateswararao Jujjuri (JV) } V9fsReadState;
284fac4f111SVenkateswararao Jujjuri (JV) 
285fac4f111SVenkateswararao Jujjuri (JV) typedef struct V9fsWriteState {
286fac4f111SVenkateswararao Jujjuri (JV)     V9fsPDU *pdu;
287fac4f111SVenkateswararao Jujjuri (JV)     size_t offset;
288fac4f111SVenkateswararao Jujjuri (JV)     int32_t len;
289fac4f111SVenkateswararao Jujjuri (JV)     int32_t count;
290fac4f111SVenkateswararao Jujjuri (JV)     int32_t total;
291fac4f111SVenkateswararao Jujjuri (JV)     int64_t off;
292fac4f111SVenkateswararao Jujjuri (JV)     V9fsFidState *fidp;
293fac4f111SVenkateswararao Jujjuri (JV)     struct iovec iov[128]; /* FIXME: bad, bad, bad */
294fac4f111SVenkateswararao Jujjuri (JV)     struct iovec *sg;
295fac4f111SVenkateswararao Jujjuri (JV)     int cnt;
296fac4f111SVenkateswararao Jujjuri (JV) } V9fsWriteState;
297fac4f111SVenkateswararao Jujjuri (JV) 
298c79ce737SSripathi Kodi typedef struct V9fsIattr
299c79ce737SSripathi Kodi {
300c79ce737SSripathi Kodi     int32_t valid;
301c79ce737SSripathi Kodi     int32_t mode;
302c79ce737SSripathi Kodi     int32_t uid;
303c79ce737SSripathi Kodi     int32_t gid;
304c79ce737SSripathi Kodi     int64_t size;
305c79ce737SSripathi Kodi     int64_t atime_sec;
306c79ce737SSripathi Kodi     int64_t atime_nsec;
307c79ce737SSripathi Kodi     int64_t mtime_sec;
308c79ce737SSripathi Kodi     int64_t mtime_nsec;
309c79ce737SSripathi Kodi } V9fsIattr;
310c79ce737SSripathi Kodi 
3119f107513SAnthony Liguori struct virtio_9p_config
3129f107513SAnthony Liguori {
3139f107513SAnthony Liguori     /* number of characters in tag */
3149f107513SAnthony Liguori     uint16_t tag_len;
3159f107513SAnthony Liguori     /* Variable size tag name */
3169f107513SAnthony Liguori     uint8_t tag[0];
317*541dc0d4SStefan Weil } QEMU_PACKED;
3189f107513SAnthony Liguori 
3195268ceccSM. Mohan Kumar typedef struct V9fsMkState {
3205268ceccSM. Mohan Kumar     V9fsPDU *pdu;
3215268ceccSM. Mohan Kumar     size_t offset;
3225268ceccSM. Mohan Kumar     V9fsQID qid;
3235268ceccSM. Mohan Kumar     struct stat stbuf;
3245268ceccSM. Mohan Kumar     V9fsString name;
3255268ceccSM. Mohan Kumar     V9fsString fullname;
3265268ceccSM. Mohan Kumar } V9fsMkState;
3275268ceccSM. Mohan Kumar 
32882cc3ee8SM. Mohan Kumar #define P9_LOCK_SUCCESS 0
32982cc3ee8SM. Mohan Kumar #define P9_LOCK_BLOCKED 1
33082cc3ee8SM. Mohan Kumar #define P9_LOCK_ERROR 2
33182cc3ee8SM. Mohan Kumar #define P9_LOCK_GRACE 3
33282cc3ee8SM. Mohan Kumar 
33382cc3ee8SM. Mohan Kumar #define P9_LOCK_FLAGS_BLOCK 1
33482cc3ee8SM. Mohan Kumar #define P9_LOCK_FLAGS_RECLAIM 2
33582cc3ee8SM. Mohan Kumar 
33682cc3ee8SM. Mohan Kumar typedef struct V9fsFlock
33782cc3ee8SM. Mohan Kumar {
33882cc3ee8SM. Mohan Kumar     uint8_t type;
33982cc3ee8SM. Mohan Kumar     uint32_t flags;
34082cc3ee8SM. Mohan Kumar     uint64_t start; /* absolute offset */
34182cc3ee8SM. Mohan Kumar     uint64_t length;
34282cc3ee8SM. Mohan Kumar     uint32_t proc_id;
34382cc3ee8SM. Mohan Kumar     V9fsString client_id;
34482cc3ee8SM. Mohan Kumar } V9fsFlock;
34582cc3ee8SM. Mohan Kumar 
3468f354003SM. Mohan Kumar typedef struct V9fsGetlock
3478f354003SM. Mohan Kumar {
3488f354003SM. Mohan Kumar     uint8_t type;
3498f354003SM. Mohan Kumar     uint64_t start; /* absolute offset */
3508f354003SM. Mohan Kumar     uint64_t length;
3518f354003SM. Mohan Kumar     uint32_t proc_id;
3528f354003SM. Mohan Kumar     V9fsString client_id;
3538f354003SM. Mohan Kumar } V9fsGetlock;
3548f354003SM. Mohan Kumar 
35564b85a8fSBlue Swirl size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
3569f107513SAnthony Liguori                       size_t offset, size_t size, int pack);
3579f107513SAnthony Liguori 
3589f107513SAnthony Liguori static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
3599f107513SAnthony Liguori                         size_t offset, size_t size)
3609f107513SAnthony Liguori {
3619f107513SAnthony Liguori     return pdu_packunpack(dst, sg, sg_count, offset, size, 0);
3629f107513SAnthony Liguori }
3639f107513SAnthony Liguori 
364f4f61d27SAneesh Kumar K.V extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq);
3659f107513SAnthony Liguori #endif
366