1 | /*************************************** 2 | $Revision: 1.15 $ 3 | 4 | Miscellaneous functions to support UD 5 | 6 | Status: NOT REVUED, NOT TESTED 7 | 8 | Author(s): Chris Ottrey, Andrei Robachevsky 9 | 10 | ******************/ /****************** 11 | Modification History: 12 | andrei (17/01/2000) Created. 13 | ******************/ /****************** 14 | Copyright (c) 2000 RIPE NCC 15 | 16 | All Rights Reserved 17 | 18 | Permission to use, copy, modify, and distribute this software and its 19 | documentation for any purpose and without fee is hereby granted, 20 | provided that the above copyright notice appear in all copies and that 21 | both that copyright notice and this permission notice appear in 22 | supporting documentation, and that the name of the author not be 23 | used in advertising or publicity pertaining to distribution of the 24 | software without specific, written prior permission. 25 | 26 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 27 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 28 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 29 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 30 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 31 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 32 | ***************************************/ 33 | #include "ud.h" 34 | #include "ud_int.h" 35 | /************************************************************ 36 | * void attribute_free() * 37 | * * 38 | * Frees memory allocated for an attribute * 39 | * * 40 | ************************************************************/ 41 | void attribute_free(void *data, void *ptr) 42 | { 43 | Attribute_t *attr = data; 44 | 45 | free(attr->value); 46 | free(attr); 47 | } 48 | 49 | /************************************************************ 50 | * Attribute_t *attribute_upd() * 51 | * * 52 | * Changes the value of an attribute * 53 | * * 54 | ************************************************************/ 55 | Attribute_t *attribute_upd(Attribute_t *attr, int newtype, char *newvalue) 56 | { 57 | attr->type=newtype; 58 | free(attr->value); 59 | attr->value=g_strdup(newvalue); 60 | if(!attr->value)die; 61 | return(attr); 62 | } 63 | 64 | /************************************************************ 65 | * Attribute_t *attribute_new1() * 66 | * * 67 | * Creates an attribute and fills the type and value * 68 | * * 69 | ************************************************************/ 70 | Attribute_t *attribute_new1(int type, const char *value) 71 | { 72 | char *n; 73 | Attribute_t *attr = NULL; 74 | 75 | attr = (Attribute_t *)calloc(1, sizeof(Attribute_t)+1); 76 | if(!attr) die; 77 | attr->type = type; 78 | 79 | /* check for end-of-line comments */ 80 | n = index(value, '#'); 81 | /* if there is no comment check for trailing \n */ 82 | if(n == NULL) n = index(value, '\n'); 83 | /* now copy the clean value into the attribute */ 84 | if(n == NULL) attr->value = g_strdup(value); 85 | else attr->value = g_strndup(value, (n - value)); 86 | /* Strip the whitespace */ 87 | g_strstrip(attr->value); 88 | return(attr); 89 | 90 | } 91 | /************************************************************ 92 | * Attribute_t *attribute_new() * 93 | * * 94 | * Determines the type and value of an attribute and * 95 | * creates it by calling attribute_new1() * 96 | * * 97 | ************************************************************/ 98 | Attribute_t *attribute_new(const char *line) { 99 | Attribute_t *attr = NULL; 100 | int type; 101 | char *colon; 102 | gchar *token; 103 | 104 | 105 | colon = index(line, ':'); 106 | if (colon != NULL) { 107 | if (line[0] =='*') { 108 | token = g_strndup(line+1, 2); 109 | type = DF_attribute_code2type(token); 110 | } 111 | else { 112 | token = g_strndup(line, (colon - line)); 113 | type = DF_attribute_name2type(token); 114 | } 115 | if(token)free(token); 116 | 117 | colon+=2; 118 | if (type >= 0) { 119 | attr=attribute_new1(type, colon); 120 | } 121 | } 122 | return attr; 123 | } /* attribute_new() */ 124 | 125 | /************************************************************ 126 | * void object_free() * 127 | * * 128 | * Frees memory allocated for an object * 129 | * * 130 | ************************************************************/ 131 | void object_free(Object_t *obj) { 132 | if (obj) { 133 | g_slist_foreach(obj->attributes, attribute_free, NULL); 134 | g_slist_free(obj->attributes); 135 | g_string_free(obj->object, TRUE); 136 | free(obj); 137 | } 138 | } /* object_free() */ 139 | 140 | /************************************************************ 141 | * Object_t *object_new() * 142 | * * 143 | * Determines the class type and creates an object * 144 | * * 145 | ************************************************************/ 146 | Object_t *object_new(const char *line) { 147 | Object_t *obj = NULL; 148 | 149 | int type; 150 | char *colon; 151 | gchar *token=NULL; 152 | 153 | colon = index(line, ':'); 154 | if (colon != NULL) { 155 | if (line[0] =='*') { 156 | token = g_strndup(line+1, 2); 157 | type = DF_class_code2type(token); 158 | } 159 | else { 160 | token = g_strndup(line, (colon - line)); 161 | type = DF_class_name2type(token); 162 | } 163 | if(token)free(token); 164 | 165 | if (type >= 0) { 166 | obj = (Object_t *)calloc(1, sizeof(Object_t)+1); 167 | if(!obj) die; 168 | obj->attributes = NULL; 169 | obj->object = g_string_sized_new(STR_XXXL); 170 | obj->type = type; 171 | } 172 | } 173 | return obj; 174 | } /* object_new() */ 175 | 176 | 177 | /************************************************************ 178 | * void transaction_free() * 179 | * * 180 | * Frees memory allocated for a transaction * 181 | * * 182 | ************************************************************/ 183 | 184 | void transaction_free(Transaction_t *tr) { 185 | if(tr) { 186 | g_string_free(tr->error_script, TRUE); 187 | g_string_free(tr->K, TRUE); 188 | /* free nic_handle_t structure used for NHR stuff */ 189 | if(tr->nh)free_nh(tr->nh); 190 | if(tr->save){ 191 | /* fprintf(stderr, "FREED [%s]\n", tr->save); */ 192 | free(tr->save); 193 | } 194 | if(tr->packptr)free(tr->packptr); 195 | free(tr); 196 | } 197 | } /* transaction_free() */ 198 | 199 | /************************************************************ 200 | * Transaction_t *transaction_new() * 201 | * * 202 | * Creates a transaction * 203 | * * 204 | ************************************************************/ 205 | Transaction_t *transaction_new(SQ_connection_t *sql_connection, C_Type_t class_type) { 206 | Transaction_t *tr = (Transaction_t *)calloc(1, sizeof(Transaction_t)); 207 | 208 | if (tr != NULL) { 209 | tr->sql_connection = sql_connection; 210 | tr->class_type = class_type; 211 | tr->thread_upd=TR_UPDATE; 212 | tr->thread_ins=TR_INSERT; 213 | tr->succeeded = 1; 214 | tr->error_script = g_string_sized_new(STR_XL); 215 | tr->K = g_string_sized_new(STR_L); 216 | tr->sequence_id=1; /* we start from 1*/ 217 | tr->packptr=calloc(1, sizeof(rp_upd_pack_t)); 218 | 219 | } 220 | else die; 221 | return tr; 222 | } /* transaction_new() */ 223 | /************************************************************ 224 | * int UD_ack() * 225 | * 226 | * Sends an acknowledgement to DBupdate and receives a reply * * 227 | * * 228 | * Return codes: * 229 | * * 230 | * 0 - OK 231 | * -1 - 232 | ************************************************************/ 233 | int UD_ack(Transaction_t* tr) 234 | { 235 | GString *g_buff; 236 | int res, error; 237 | 238 | /* if we are not in update/server mode - no ack is needed - just return */ 239 | if(IS_STANDALONE(tr->mode)) return(0); 240 | if(!IS_UPDATE(tr->mode)) return(0); 241 | 242 | if ((g_buff = g_string_sized_new(STR_L)) == NULL){ 243 | ER_perror(FAC_UD, UD_MEM, "cannot allocate gstring\n"); 244 | die; 245 | } 246 | 247 | if(tr->succeeded==0) { /* update failed */ 248 | error = tr->error; 249 | } 250 | else error = 0; 251 | 252 | g_string_sprintf(g_buff, "%%ERROR %d\n%s\n", error, (tr->error_script)->str); 253 | res = SK_puts(tr->socket, g_buff->str); 254 | g_string_free(g_buff, TRUE); 255 | /* close the connection */ 256 | /* Let DBupdate close the connection */ 257 | /* close(tr->socket); */ 258 | return(res); 259 | } 260 |