1    | /***************************************
2    |   $Revision: 1.16 $
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, NULL);
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  |