1 /********************************************************************** 2 * token.h September 1999 3 * Horms horms@verge.net.au 4 * 5 * Token to encapsulate a byte string 6 * 7 * perdition 8 * Mail retrieval proxy server 9 * Copyright (C) 1999-2005 Horms 10 * 11 * This program is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU General Public License as 13 * published by the Free Software Foundation; either version 2 of the 14 * License, or (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software Foundation, 23 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 24 * 25 **********************************************************************/ 26 27 #ifndef TOKEN_BLUM 28 #define TOKEN_BLUM 29 30 #include <sys/time.h> 31 #include <sys/types.h> 32 #include <unistd.h> 33 #include <string.h> 34 #include <stdlib.h> 35 #include <stdio.h> 36 #include <ctype.h> 37 #include <vanessa_socket.h> 38 39 #include "log.h" 40 #include "str.h" 41 #include "perdition_types.h" 42 43 #define BUFFER_SIZE (size_t)1024 44 45 #define TOKEN_DESTROY (void (*)(const void *))token_destroy 46 47 typedef struct{ 48 size_t n; 49 char *buf; 50 flag_t flag; 51 }token_t; 52 53 /* 54 * Flags for Tokens 55 */ 56 #define TOKEN_NONE (flag_t) 0x00 /* No flag (NULL state) */ 57 #define TOKEN_EOL (flag_t) 0x01 /* Token is at the end of a line */ 58 #define TOKEN_DONT_CARE (flag_t) 0x03 /* Don't care what token is. 59 Used for comparisons */ 60 61 /* 62 * Flags for tokeniser 63 */ 64 /* #define TOKEN_EOL, defined above */ 65 #define TOKEN_POP3 (flag_t) 0x02 66 #define TOKEN_ACAP_ATOM TOKEN_POP3 67 #define TOKEN_IMAP4 (flag_t) 0x04 68 #define TOKEN_MANAGESIEVE TOKEN_IMAP4 69 #define TOKEN_IMAP4_LITERAL (flag_t) 0x08 70 #define TOKEN_ACAP_LITERAL TOKEN_IMAP4_LITERAL 71 72 #define TOKEN_NO_STRIP (unsigned char) '\0' 73 74 token_t *create_token(void); 75 76 77 /********************************************************************** 78 * token_create 79 * create an empty token 80 * pre: none 81 * post: token is created, and values are initialised 82 * return: allocated token_t 83 * NULL on error 84 * 85 * 8 bit clean 86 **********************************************************************/ 87 88 token_t *token_create(void); 89 90 91 /********************************************************************** 92 * token_assign 93 * place bytes into a token 94 * pre: t: token to place bytes in 95 * buf: buffer to use 96 * n: number of bytes in buffer 97 * flags: flags for token as per token.h 98 * post: if n!=0 then buf is used as the buffer in t 99 * (no copying) 100 * if n==0 the buffer in t is set to NULL 101 * the flag in t is set 102 * return: none 103 * 104 * 8 bit clean 105 **********************************************************************/ 106 107 void token_assign( 108 token_t *t, 109 char * buf, 110 const size_t n, 111 const flag_t flag 112 ); 113 114 115 /********************************************************************** 116 * token_unassign 117 * make a token empty 118 * useful if you want to destroy a token but not what it contains 119 * pre: t: token to unassign values of 120 * post: values in t are reinitialised, but buffer is not destroyed 121 * return: none 122 * 123 * 8 bit clean 124 **********************************************************************/ 125 126 void token_unassign(token_t *t); 127 128 129 /********************************************************************** 130 * token_destroy 131 * pre: t pointer to a token 132 * post: if the token is null no nothing 133 * if buf is non-NULL then free it 134 * free the token 135 * return: none 136 * 137 * 8 bit clean 138 **********************************************************************/ 139 140 void token_destroy(token_t **t); 141 142 143 /********************************************************************** 144 * token_write 145 * write a token to fd 146 * pre: io: io_t to write to 147 * token: token to write 148 * post: contents of token is written to fd using 149 * vanessa_socket_pipe_write_bytes 150 * return: -1 on error 151 * 0 otherwise 152 * 153 * 8 bit clean 154 **********************************************************************/ 155 156 int token_write(io_t *io, const token_t *t); 157 158 159 /********************************************************************** 160 * token_flush 161 * Flush internal buffers used to read tokens. 162 * pre: none 163 * post: internal buffers are flushed 164 * return: none 165 **********************************************************************/ 166 167 void token_flush(void); 168 169 170 /********************************************************************** 171 * token_read 172 * read a token in from fd 173 * pre: io: io_t to read from 174 * literal_buf: buffer to store bytes read from server in 175 * n: pointer to size_t containing the size of literal_buf 176 * flag: If logical or of TOKEN_EOL then all characters 177 * up to a '\n' will be read as a token. That is the token may 178 * have spaces. 179 * If logical or of TOKEN_IMAP4 then spaces inside 180 * quotes will be treated as literals rather than token 181 * delimiters. 182 * If logical or of TOKEN_IMAP4_LITERAL then m bytes 183 * will be read as a single token. 184 * m: Bytes to read if flag is TOKEN_IMAP4_LITERAL 185 * log_str: logging tag for connection logging 186 * post: Token is read from fd into token 187 * ' ' will terminate a token 188 * '\r' is ignored 189 * '\n' will terminate a token and set the eol element to 1 190 * All other characters are considered to be a part of the token 191 * If literal_buf is not NULL, and n is not NULL and *n is not 0 192 * Bytes read from fd are copied to literal_buf, this includes 193 * ' ', '\r' and '\n'. 194 * return: token 195 * NULL on error 196 * Note: if a token larger than BUFFER_SIZE is read then only 197 * BUFFER_SIZE will be read and the remainder will be 198 * left (to be handled by an subsequent call to token_read). 199 * The same applies to *n if literal_buf is being filled. 200 * 201 * 8 bit clean 202 **********************************************************************/ 203 204 token_t *token_read( 205 io_t *io, 206 char *literal_buf, 207 size_t *n, 208 flag_t flag, 209 size_t m, 210 const char *log_str 211 ); 212 213 214 /********************************************************************** 215 * token_is_eol 216 * Check if the token is at the end of a line 217 * pre: t: token to check eol flag of 218 * post: none 219 * return 1 if the token is at the end of a line 220 * 0 otherwise 221 **********************************************************************/ 222 223 #define token_is_eol(_t) ((_t)->flag&TOKEN_EOL?1:0) 224 225 226 /********************************************************************** 227 * token_buf 228 * Get the buffer of a token 229 * pre: t: token to get the buffer of 230 * post: none 231 * return: buffer of the token 232 **********************************************************************/ 233 234 #define token_buf(_t) ((_t)->buf) 235 236 237 /********************************************************************** 238 * token_len 239 * Get the length of a token 240 * pre: t: token to get the length of 241 * post: none 242 * return: length of the token 243 **********************************************************************/ 244 245 #define token_len(_t) ((_t)->n) 246 247 248 /********************************************************************** 249 * token_cmp 250 * compare two tokens 251 * pre: a: token to compare 252 * b: token to compare 253 * post: none 254 * return: 1 is they are the same 255 * 0 otherwise 256 * flag field will be ignored if either token has eol set to TOKEN_DONT_CARE 257 * 258 * Not 8 bit clean as it is case insensitive using toupper 259 **********************************************************************/ 260 261 int token_cmp(const token_t *a, const token_t *b); 262 263 264 /********************************************************************** 265 * token_is_null 266 * test if a token is null, that is has an empty payload 267 * pre: t: token to test 268 * post: none 269 * return 1 if token is null 270 * 0 otherwise 271 * t->flag is ignored 272 * 273 * 8 bit clean 274 **********************************************************************/ 275 276 #define token_is_null(_t) ((_t)->n?0:1) 277 278 279 /********************************************************************** 280 * token_to_string 281 * dump the buffer in a token into a \0 terminated string 282 * string will be dynamically allocated 283 * pre: t: token to dump to a string 284 * strip: Character to strip from first and last character of 285 * string if it is present. Ignored if TOKEN_NO_STRIP 286 * 287 * post: a string is allocated and the contents of it's buffer plus 288 * a trailing '\0' is placed in the string 289 * return: the string 290 * NULL on error 291 * 292 * Not 8 bit clean 293 **********************************************************************/ 294 295 char *token_to_string(const token_t *t, const unsigned char strip); 296 297 /********************************************************************** 298 * token_casecmp_string 299 * Compare a token with a null-terminated string 300 * pre: t: token 301 * str: string 302 * return: 1 on match 303 * 0 otherwise 304 * 305 * Not 8 bit clean 306 **********************************************************************/ 307 308 int token_casecmp_string(const token_t *t, const char *str); 309 310 #endif 311