1 /* 2 * uhub - A tiny ADC p2p connection hub 3 * Copyright (C) 2007-2014, Jan Vidar Krey 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 #ifndef HAVE_UHUB_COMMAND_H 21 #define HAVE_UHUB_COMMAND_H 22 23 struct hub_user; 24 25 struct adc_message 26 { 27 fourcc_t cmd; 28 sid_t source; 29 sid_t target; 30 char* cache; 31 size_t length; 32 size_t capacity; 33 size_t priority; 34 size_t references; 35 struct linked_list* feature_cast_include; 36 struct linked_list* feature_cast_exclude; 37 }; 38 39 enum msg_status_level 40 { 41 status_level_info = 0, /* Success/informative status message */ 42 status_level_error = 1, /* Recoverable error */ 43 status_level_fatal = 2, /* Fatal error (disconnect) */ 44 }; 45 46 /** 47 * Increase the reference counter for an ADC message struct. 48 * NOTE: Always use the returned value, and not the passed value, as 49 * it ensures we can actually copy the value if needed. 50 */ 51 extern struct adc_message* adc_msg_incref(struct adc_message* msg); 52 53 /** 54 * Decrease the reference counter, and free the memory when apropriate. 55 */ 56 extern void adc_msg_free(struct adc_message* msg); 57 58 /** 59 * Perform deep copy a command. 60 * NOTE: 'references' will be zero for the copied command. 61 * @return a copy of cmd or NULL if not able to allocate memory. 62 */ 63 extern struct adc_message* adc_msg_copy(const struct adc_message* cmd); 64 65 /** 66 * This will parse 'string' and return it as a adc_message struct, or 67 * NULL if not able to allocate memory or 'string' does not contain 68 * a valid ADC command. 69 * 70 * The message is only considered valid if the user who sent it 71 * is the rightful origin of the message. 72 */ 73 extern struct adc_message* adc_msg_parse_verify(struct hub_user* u, const char* string, size_t length); 74 75 /** 76 * This will parse 'string' and return it as a adc_message struct, or 77 * NULL if not able to allocate memory or 'string' does not contain 78 * a valid ADC command. 79 */ 80 extern struct adc_message* adc_msg_parse(const char* string, size_t length); 81 82 /** 83 * This will construct a adc_message based on 'string'. 84 * Only to be used for server generated commands. 85 */ 86 extern struct adc_message* adc_msg_create(const char* string); 87 88 /** 89 * Construct a message with the given 'fourcc' and allocate 90 * 'size' bytes for later use. 91 */ 92 extern struct adc_message* adc_msg_construct(fourcc_t fourcc, size_t size); 93 94 /** 95 * Construct a message for the given 'fourcc' and add a source SID to it, 96 * in addition pre-allocate 'size' bytes at the end of the message. 97 */ 98 extern struct adc_message* adc_msg_construct_source(fourcc_t fourcc, sid_t source, size_t size); 99 extern struct adc_message* adc_msg_construct_source_dest(fourcc_t fourcc, sid_t source, sid_t dest, size_t size); 100 101 /** 102 * Remove a named argument from the command. 103 * 104 * @arg prefix a 2 character argument prefix 105 * @return the number of named arguments removed. 106 */ 107 extern int adc_msg_remove_named_argument(struct adc_message* cmd, const char prefix[2]); 108 109 /** 110 * Count the number of arguments matching the given 2 character prefix. 111 * 112 * @arg prefix a 2 character argument prefix 113 * @return the number of matching arguments 114 */ 115 extern int adc_msg_has_named_argument(struct adc_message* cmd, const char prefix[2]); 116 117 /** 118 * Returns a named arguments based on the 2 character prefix. 119 * If multiple matching arguments exists, only the first one will be returned 120 * by this function. 121 * 122 * NOTE: Returned memory must be free'd with hub_free(). 123 * 124 * @arg prefix a 2 character argument prefix 125 * @return the argument or NULL if OOM/not found. 126 */ 127 extern char* adc_msg_get_named_argument(struct adc_message* cmd, const char prefix[2]); 128 129 /** 130 * Returns a offset of an argument based on the 2 character prefix. 131 * If multiple matching arguments exists, only the first one will be returned 132 * by this function. 133 * 134 * @arg prefix a 2 character argument prefix 135 * @return the offset or -1 if the argument is not found. 136 */ 137 extern int adc_msg_get_named_argument_index(struct adc_message* cmd, const char prefix[2]); 138 139 /** 140 * @param cmd command to be checked 141 * @return 1 if the command does not have any arguments (parameters), 0 otherwise, -1 if cmd is invalid. 142 */ 143 extern int adc_msg_is_empty(struct adc_message* cmd); 144 145 /** 146 * Returns the argument on the offset position in the command. 147 * If offset is invalid NULL is returned. 148 * 149 * NOTE: Returned memory must be free'd with hub_free(). 150 * 151 * @return the argument or NULL if OOM/not found. 152 */ 153 extern char* adc_msg_get_argument(struct adc_message* cmd, int offset); 154 155 /** 156 * Replace a named argument in the command. 157 * This will remove any matching arguments (multiple, or none), 158 * then add 'string' as an argument using the given prefix. 159 * 160 * @arg prefix a 2 character argument prefix 161 * @arg string must be escaped (see adc_msg_escape). 162 * @return 0 if successful, or -1 if an error occured. 163 */ 164 extern int adc_msg_replace_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); 165 166 /** 167 * Append an argument 168 * 169 * @arg string must be escaped (see adc_msg_escape). 170 * @return 0 if successful, or -1 if an error occured (out of memory). 171 */ 172 extern int adc_msg_add_argument(struct adc_message* cmd, const char* string); 173 174 /** 175 * Append a named argument 176 * 177 * @arg prefix a 2 character argument prefix 178 * @arg string must be escaped (see adc_msg_escape). 179 * @return 0 if successful, or -1 if an error occured (out of memory). 180 */ 181 extern int adc_msg_add_named_argument(struct adc_message* cmd, const char prefix[2], const char* string); 182 183 /** 184 * Append a string as a named argument. 185 * The string will automatcally be escaped, if you do not wish to escape th string use adc_msg_add_named_argument() instead. 186 * 187 * @arg prefix a 2 character argument prefix 188 * @arg string must NOT be escaped 189 * @return 0 if successful, or -1 if an error occured (out of memory). 190 */ 191 extern int adc_msg_add_named_argument_string(struct adc_message* cmd, const char prefix[2], const char* string); 192 193 /** 194 * Append an integer as a named argument. 195 */ 196 extern int adc_msg_add_named_argument_int(struct adc_message* cmd, const char prefix[2], int integer); 197 extern int adc_msg_add_named_argument_uint64(struct adc_message* cmd, const char prefix[2], uint64_t num); 198 199 /** 200 * Convert a ADC command escaped string to a regular string. 201 * @return string or NULL if out of memory 202 */ 203 extern char* adc_msg_unescape(const char* string); 204 205 /** 206 * Convert a ADC command escaped string to a regular string. 207 * @return The number of bytes written to target. If the target is not large enough then 208 * the -1 is returned, but the string is guaranteed to always be \0 terminated. 209 */ 210 extern int adc_msg_unescape_to_target(const char* string, char* target, size_t target_size); 211 212 213 /** 214 * Convert a string to a ADC command escaped string. 215 * @return adc command escaped string or NULL if out of memory. 216 */ 217 extern char* adc_msg_escape(const char* string); 218 219 /** 220 * This will ensure a newline is at the end of the command. 221 */ 222 void adc_msg_terminate(struct adc_message* cmd); 223 224 /** 225 * This will remove any newline from the end of the command 226 */ 227 void adc_msg_unterminate(struct adc_message* cmd); 228 229 /** 230 * @return the offset for the first command argument in msg->cache. 231 * or -1 if the command is not understood. 232 * NOTE: for 'U' and 'C' commands (normally not seen by hubs), 233 * this returns 4. Should be 4 + lengthOf(cid). 234 */ 235 int adc_msg_get_arg_offset(struct adc_message* msg); 236 237 #endif /* HAVE_UHUB_COMMAND_H */ 238