Showing the changes to c9.h (1 of 4 files). Show all
Unified · Split
| @@ -0,0 +1,350 @@ | |||
| 1 | struct C9aux; | ||
| 2 | |||
| 3 | typedef struct C9r C9r; | ||
| 4 | typedef struct C9t C9t; | ||
| 5 | typedef struct C9stat C9stat; | ||
| 6 | typedef struct C9ctx C9ctx; | ||
| 7 | typedef struct C9qid C9qid; | ||
| 8 | typedef enum C9error C9error; | ||
| 9 | typedef enum C9mode C9mode; | ||
| 10 | typedef enum C9rtype C9rtype; | ||
| 11 | typedef enum C9ttype C9ttype; | ||
| 12 | typedef enum C9qt C9qt; | ||
| 13 | typedef uint32_t C9fid; | ||
| 14 | typedef uint16_t C9tag; | ||
| 15 | |||
| 16 | /* Stat field is not changed if it's set to this value when calling c9wstat. */ | ||
| 17 | #define C9nochange (~0) | ||
| 18 | |||
| 19 | /* Special fid used with auth/attach to basically avoid authentication. */ | ||
| 20 | #define C9nofid ((C9fid)~0) | ||
| 21 | |||
| 22 | /* C9modes for opening a file. */ | ||
| 23 | enum C9mode | ||
| 24 | { | ||
| 25 | C9read = 0, | ||
| 26 | C9write = 1, | ||
| 27 | C9rdwr = 2, | ||
| 28 | C9exec = 3, | ||
| 29 | C9trunc = 0x10, | ||
| 30 | C9rclose = 0x40, | ||
| 31 | }; | ||
| 32 | |||
| 33 | enum C9perm | ||
| 34 | { | ||
| 35 | /* User/owner. */ | ||
| 36 | C9permur = 1<<8, /* Readable. */ | ||
| 37 | C9permuw = 1<<7, /* Writable. */ | ||
| 38 | C9permux = 1<<6, /* Executable. */ | ||
| 39 | |||
| 40 | /* Group. */ | ||
| 41 | C9permgr = 1<<5, | ||
| 42 | C9permgw = 1<<4, | ||
| 43 | C9permgx = 1<<3, | ||
| 44 | |||
| 45 | /* Other. */ | ||
| 46 | C9permor = 1<<2, | ||
| 47 | C9permow = 1<<1, | ||
| 48 | C9permox = 1<<0, | ||
| 49 | }; | ||
| 50 | |||
| 51 | /* Directory. */ | ||
| 52 | #define C9permdir 0x80000000 | ||
| 53 | |||
| 54 | /* Bitmask of stat.mode. */ | ||
| 55 | #define C9stdir 0x80000000 | ||
| 56 | #define C9stappend 0x40000000 | ||
| 57 | #define C9stexcl 0x20000000 | ||
| 58 | #define C9sttmp 0x04000000 | ||
| 59 | |||
| 60 | /* Limits. */ | ||
| 61 | enum | ||
| 62 | { | ||
| 63 | C9maxtags = 64, /* Maximal number of outstanding requests. [1-65535] */ | ||
| 64 | C9maxflush = 8, /* Maximal number of outstanding flushes. [1-65535] */ | ||
| 65 | C9maxstr = 0xffff, /* Maximal string length. [1-65535] */ | ||
| 66 | C9minmsize = 4096, /* Minimal sane msize. [4096-...] */ | ||
| 67 | C9maxpathel = 16, /* Maximal number of elements in a path. Do not change. */ | ||
| 68 | }; | ||
| 69 | |||
| 70 | /* Errors. */ | ||
| 71 | enum C9error | ||
| 72 | { | ||
| 73 | C9Einit = -1, /* Initialization failed. */ | ||
| 74 | C9Ever = -2, /* Protocol version doesn't match. */ | ||
| 75 | C9Epkt = -3, /* Incoming packet error. */ | ||
| 76 | C9Etag = -4, /* No free tags or bad tag. */ | ||
| 77 | C9Ebuf = -5, /* No buffer space enough for a message. */ | ||
| 78 | C9Epath = -6, /* Path is too long or just invalid. */ | ||
| 79 | C9Eflush = -7, /* Limit of outstanding flushes reached. */ | ||
| 80 | C9Esize = -8, /* Can't fit data in one message. */ | ||
| 81 | C9Estr = -9 /* Bad string. */ | ||
| 82 | }; | ||
| 83 | |||
| 84 | /* Request types. */ | ||
| 85 | enum C9ttype | ||
| 86 | { | ||
| 87 | Tversion = 100, | ||
| 88 | Tauth = 102, | ||
| 89 | Tattach = 104, | ||
| 90 | Tflush = 108, | ||
| 91 | Twalk = 110, | ||
| 92 | Topen = 112, | ||
| 93 | Tcreate = 114, | ||
| 94 | Tread = 116, | ||
| 95 | Twrite = 118, | ||
| 96 | Tclunk = 120, | ||
| 97 | Tremove = 122, | ||
| 98 | Tstat = 124, | ||
| 99 | Twstat = 126 | ||
| 100 | }; | ||
| 101 | |||
| 102 | /* Response types. */ | ||
| 103 | enum C9rtype | ||
| 104 | { | ||
| 105 | Rversion = 101, | ||
| 106 | Rauth = 103, | ||
| 107 | Rattach = 105, | ||
| 108 | Rerror = 107, | ||
| 109 | Rflush = 109, | ||
| 110 | Rwalk = 111, | ||
| 111 | Ropen = 113, | ||
| 112 | Rcreate = 115, | ||
| 113 | Rread = 117, | ||
| 114 | Rwrite = 119, | ||
| 115 | Rclunk = 121, | ||
| 116 | Rremove = 123, | ||
| 117 | Rstat = 125, | ||
| 118 | Rwstat = 127 | ||
| 119 | }; | ||
| 120 | |||
| 121 | /* Unique file id type. */ | ||
| 122 | enum C9qt | ||
| 123 | { | ||
| 124 | C9qtdir = 1<<7, | ||
| 125 | C9qtappend = 1<<6, | ||
| 126 | C9qtexcl = 1<<5, | ||
| 127 | C9qtauth = 1<<3, | ||
| 128 | C9qttmp = 1<<2, | ||
| 129 | C9qtfile = 0 | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* Unique file id. */ | ||
| 133 | struct C9qid | ||
| 134 | { | ||
| 135 | uint64_t path; | ||
| 136 | uint32_t version; | ||
| 137 | C9qt type; | ||
| 138 | }; | ||
| 139 | |||
| 140 | /* | ||
| 141 | * File stats. Version and muid are ignored on wstat. Dmdir bit | ||
| 142 | * change in mode won't work on wstat. Set any integer field to | ||
| 143 | * C9nochange to keep it unchanged on wstat. Set any string to NULL to | ||
| 144 | * keep it unchanged. Strings can be empty (""), but never NULL after | ||
| 145 | * stat call. | ||
| 146 | */ | ||
| 147 | struct C9stat | ||
| 148 | { | ||
| 149 | uint64_t size; /* Size of the file (in bytes). */ | ||
| 150 | char *name; /* Name of the file. */ | ||
| 151 | char *uid; /* Owner of the file. */ | ||
| 152 | char *gid; /* Group of the file. */ | ||
| 153 | char *muid; /* The user who modified the file last. */ | ||
| 154 | C9qid qid; /* Same as qid[0]. */ | ||
| 155 | uint32_t mode; /* Permissions. See C9st* and C9perm. */ | ||
| 156 | uint32_t atime; /* Last access time. */ | ||
| 157 | uint32_t mtime; /* Last modification time. */ | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* Response data. */ | ||
| 161 | struct C9r | ||
| 162 | { | ||
| 163 | union | ||
| 164 | { | ||
| 165 | char *error; | ||
| 166 | |||
| 167 | struct | ||
| 168 | { | ||
| 169 | uint8_t *data; | ||
| 170 | uint32_t size; | ||
| 171 | }read; | ||
| 172 | |||
| 173 | struct | ||
| 174 | { | ||
| 175 | uint32_t size; | ||
| 176 | }write; | ||
| 177 | |||
| 178 | /* File stats (only valid if type is Rstat). */ | ||
| 179 | C9stat stat; | ||
| 180 | |||
| 181 | /* | ||
| 182 | * Qid(s). qid[0] is valid for auth/attach/create/stat/open. | ||
| 183 | * More ids may be a result of a walk, see numqid. | ||
| 184 | */ | ||
| 185 | C9qid qid[C9maxpathel]; | ||
| 186 | }; | ||
| 187 | C9rtype type; /* Response type. */ | ||
| 188 | |||
| 189 | /* | ||
| 190 | * If not zero, is the maximum number of bytes that are guaranteed | ||
| 191 | * to be read or written atomically, without breaking into multiple | ||
| 192 | * messages. | ||
| 193 | */ | ||
| 194 | uint32_t iounit; | ||
| 195 | |||
| 196 | int numqid; /* Number of valid unique ids in qid array. */ | ||
| 197 | C9tag tag; /* Tag number. */ | ||
| 198 | }; | ||
| 199 | |||
| 200 | /* Request data. */ | ||
| 201 | struct C9t | ||
| 202 | { | ||
| 203 | C9ttype type; | ||
| 204 | C9tag tag; | ||
| 205 | union | ||
| 206 | { | ||
| 207 | struct | ||
| 208 | { | ||
| 209 | char *uname; | ||
| 210 | char *aname; | ||
| 211 | C9fid afid; | ||
| 212 | }attach; | ||
| 213 | |||
| 214 | struct | ||
| 215 | { | ||
| 216 | char *uname; | ||
| 217 | char *aname; | ||
| 218 | C9fid afid; | ||
| 219 | }auth; | ||
| 220 | |||
| 221 | struct | ||
| 222 | { | ||
| 223 | char *name; | ||
| 224 | uint32_t perm; | ||
| 225 | C9mode mode; | ||
| 226 | }create; | ||
| 227 | |||
| 228 | struct | ||
| 229 | { | ||
| 230 | C9tag oldtag; | ||
| 231 | }flush; | ||
| 232 | |||
| 233 | struct | ||
| 234 | { | ||
| 235 | C9mode mode; | ||
| 236 | }open; | ||
| 237 | |||
| 238 | struct | ||
| 239 | { | ||
| 240 | uint64_t offset; | ||
| 241 | uint32_t size; | ||
| 242 | }read; | ||
| 243 | |||
| 244 | struct | ||
| 245 | { | ||
| 246 | char *wname[C9maxpathel+1]; /* wname[16] is always NULL */ | ||
| 247 | C9fid newfid; | ||
| 248 | }walk; | ||
| 249 | |||
| 250 | struct | ||
| 251 | { | ||
| 252 | uint64_t offset; | ||
| 253 | uint8_t *data; | ||
| 254 | uint32_t size; | ||
| 255 | }write; | ||
| 256 | |||
| 257 | C9stat wstat; | ||
| 258 | }; | ||
| 259 | C9fid fid; | ||
| 260 | }; | ||
| 261 | |||
| 262 | enum | ||
| 263 | { | ||
| 264 | C9tagsbits = sizeof(uint32_t) * 8, | ||
| 265 | }; | ||
| 266 | |||
| 267 | struct C9ctx | ||
| 268 | { | ||
| 269 | /* | ||
| 270 | * Should return a pointer to the data (exactly 'size' bytes) read. | ||
| 271 | * Set 'err' to non-zero and return NULL in case of error. | ||
| 272 | * 'err' set to zero (no error) should be used to return from c9process | ||
| 273 | * early (timeout on read to do non-blocking operations, for example). | ||
| 274 | */ | ||
| 275 | uint8_t *(*read)(C9ctx *ctx, uint32_t size, int *err) __attribute__((nonnull(1, 3))); | ||
| 276 | |||
| 277 | /* Should return a buffer to store 'size' bytes. Nil means no memory. */ | ||
| 278 | uint8_t *(*begin)(C9ctx *ctx, uint32_t size) __attribute__((nonnull(1))); | ||
| 279 | |||
| 280 | /* | ||
| 281 | * Marks the end of a message. Callback may decide if any accumulated | ||
| 282 | * messages should be sent to the server/client. | ||
| 283 | */ | ||
| 284 | int (*end)(C9ctx *ctx) __attribute__((nonnull(1))); | ||
| 285 | |||
| 286 | /* Callback called every time a new R-message is received. */ | ||
| 287 | void (*r)(C9ctx *ctx, C9r *r) __attribute__((nonnull(1, 2))); | ||
| 288 | |||
| 289 | /* Callback called every time a new T-message is received. */ | ||
| 290 | void (*t)(C9ctx *ctx, C9t *t) __attribute__((nonnull(1, 2))); | ||
| 291 | |||
| 292 | /* Callback for error messages. */ | ||
| 293 | void (*error)(const char *fmt, ...) __attribute__((nonnull(1))); | ||
| 294 | |||
| 295 | /* Auxiliary data, can be used by any of above callbacks. */ | ||
| 296 | struct C9aux *aux; | ||
| 297 | |||
| 298 | /* private stuff */ | ||
| 299 | uint32_t msize; | ||
| 300 | uint32_t flush[C9maxflush]; | ||
| 301 | uint32_t tags[C9maxtags/C9tagsbits]; | ||
| 302 | union | ||
| 303 | { | ||
| 304 | C9tag lowfreetag; | ||
| 305 | uint16_t svflags; | ||
| 306 | }; | ||
| 307 | }; | ||
| 308 | |||
| 309 | /* Parse one directory entry. */ | ||
| 310 | extern C9error c9parsedir(C9ctx *c, C9stat *stat, uint8_t **data, uint32_t *size) __attribute__((nonnull(1, 2, 3))); | ||
| 311 | |||
| 312 | extern C9error c9version(C9ctx *c, C9tag *tag, uint32_t msize) __attribute__((nonnull(1, 2))); | ||
| 313 | extern C9error c9auth(C9ctx *c, C9tag *tag, C9fid afid, const char *uname, const char *aname) __attribute__((nonnull(1, 2))); | ||
| 314 | extern C9error c9flush(C9ctx *c, C9tag *tag, C9tag oldtag) __attribute__((nonnull(1, 2))); | ||
| 315 | extern C9error c9attach(C9ctx *c, C9tag *tag, C9fid fid, C9fid afid, const char *uname, const char *aname) __attribute__((nonnull(1, 2))); | ||
| 316 | extern C9error c9walk(C9ctx *c, C9tag *tag, C9fid fid, C9fid newfid, const char *path[]) __attribute__((nonnull(1, 2, 5))); | ||
| 317 | extern C9error c9open(C9ctx *c, C9tag *tag, C9fid fid, C9mode mode) __attribute__((nonnull(1, 2))); | ||
| 318 | extern C9error c9create(C9ctx *c, C9tag *tag, C9fid fid, const char *name, uint32_t perm, C9mode mode) __attribute__((nonnull(1, 2, 4))); | ||
| 319 | extern C9error c9read(C9ctx *c, C9tag *tag, C9fid fid, uint64_t offset, uint32_t count) __attribute__((nonnull(1, 2))); | ||
| 320 | extern C9error c9write(C9ctx *c, C9tag *tag, C9fid fid, uint64_t offset, const void *in, uint32_t count) __attribute__((nonnull(1, 2, 5))); | ||
| 321 | extern C9error c9wrstr(C9ctx *c, C9tag *tag, C9fid fid, const char *s) __attribute__((nonnull(1, 2, 4))); | ||
| 322 | extern C9error c9clunk(C9ctx *c, C9tag *tag, C9fid fid) __attribute__((nonnull(1, 2))); | ||
| 323 | extern C9error c9remove(C9ctx *c, C9tag *tag, C9fid fid) __attribute__((nonnull(1, 2))); | ||
| 324 | extern C9error c9stat(C9ctx *c, C9tag *tag, C9fid fid) __attribute__((nonnull(1, 2))); | ||
| 325 | extern C9error c9wstat(C9ctx *c, C9tag *tag, C9fid fid, const C9stat *s) __attribute__((nonnull(1, 2, 4))); | ||
| 326 | |||
| 327 | /* | ||
| 328 | * Wait until a response comes and process it. If the function returns | ||
| 329 | * any error, context must be treated as 'broken' and no subsequent calls | ||
| 330 | * should be made without reinitialization (c9version). | ||
| 331 | */ | ||
| 332 | extern C9error c9proc(C9ctx *c) __attribute__((nonnull(1))); | ||
| 333 | |||
| 334 | extern C9error s9version(C9ctx *c) __attribute__((nonnull(1))); | ||
| 335 | extern C9error s9auth(C9ctx *c, C9tag tag, const C9qid *aqid) __attribute__((nonnull(1, 3))); | ||
| 336 | extern C9error s9error(C9ctx *c, C9tag tag, const char *err) __attribute__((nonnull(1))); | ||
| 337 | extern C9error s9attach(C9ctx *c, C9tag tag, const C9qid *qid) __attribute__((nonnull(1, 3))); | ||
| 338 | extern C9error s9flush(C9ctx *c, C9tag tag) __attribute__((nonnull(1))); | ||
| 339 | extern C9error s9walk(C9ctx *c, C9tag tag, C9qid *qids[]) __attribute__((nonnull(1, 3))); | ||
| 340 | extern C9error s9open(C9ctx *c, C9tag tag, const C9qid *qid, uint32_t iounit) __attribute__((nonnull(1, 3))); | ||
| 341 | extern C9error s9create(C9ctx *c, C9tag tag, const C9qid *qid, uint32_t iounit) __attribute__((nonnull(1, 3))); | ||
| 342 | extern C9error s9read(C9ctx *c, C9tag tag, const void *data, uint32_t size) __attribute__((nonnull(1, 3))); | ||
| 343 | extern C9error s9readdir(C9ctx *c, C9tag tag, C9stat *st[], int *num, uint64_t *offset, uint32_t size) __attribute__((nonnull(1, 3, 4))); | ||
| 344 | extern C9error s9write(C9ctx *c, C9tag tag, uint32_t size) __attribute__((nonnull(1))); | ||
| 345 | extern C9error s9clunk(C9ctx *c, C9tag tag) __attribute__((nonnull(1))); | ||
| 346 | extern C9error s9remove(C9ctx *c, C9tag tag) __attribute__((nonnull(1))); | ||
| 347 | extern C9error s9stat(C9ctx *c, C9tag tag, const C9stat *s) __attribute__((nonnull(1, 3))); | ||
| 348 | extern C9error s9wstat(C9ctx *c, C9tag tag) __attribute__((nonnull(1))); | ||
| 349 | |||
| 350 | extern C9error s9proc(C9ctx *c) __attribute__((nonnull(1))); | ||