modules/up/UP_util.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- authorise
- error_msg_cat
- interpret_ripdb_result
- get_assigned_nic
- delete_override
- up_get_transaction_id
- send_object_db
- get_class_type
- get_search_key
- send_and_get
- count_objects
- strip_lines
- take_objects
- take_object
- get_as_block
- get_aut_num_object
- get_less_specific_domain
- get_less_specific_set
- get_less_specific
- get_less_spec_inetnum
- get_exact_match_inetnum
- get_exact_match_routes
- get_less_spec_routes
- get_mntners
- get_attributes
- get_attribute
- strstr_in_list
- get_auths
- get_attr_list
- get_mnt_lowers
- get_mnt_routes
- get_mnt_routes_from_list
- get_mnt_lowers_from_list
- get_override
- check_override
- add_to_auth_vector
- get_auth_vector
- get_mntnfy_vector
- get_updto_vector
- filter_out_diff_origins
- check_auth
- get_old_version
- process_mail_header
- up_string_pack
- delete_delete_attrib
- UP_replace_strings
- UP_replace_GStrings
- identical
- find_initials
- get_combination_from_autonic
- replace_AUTO_NIC_hdl
- replace_refs_to_AUTO_NIC_hdl
- has_AUTO_NIC_hdl
- has_ref_to_AUTO_nic_hdl
- find_email_address
- UP_remove_EOLs
- UP_replace_globals
- get_class_type_char
1 /***************************************
2 $Revision: 1.58 $
3
4 UP module utilities
5
6 Status: NOT REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (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
34 #include "dbupdate.h"
35
36 int error = 0; // a global variable to store the errors
37 char * error_msg = NULL; // a global variable to store the error messages
38 extern int tracing;
39 extern char * overridecryptedpw;
40 extern int test_mode;
41 extern char * update_host;
42 extern int update_port;
43 extern char * query_host;
44 extern int query_port;
45 extern char * humailbox;
46 extern char * autobox;
47
48 extern char *update_mail_sender;
49 extern char *update_mail_subject;
50 extern char *update_mail_date;
51 extern char *update_mail_ID;
52 extern char *update_mail_cc;
53
54 extern char *DBhost;
55 extern int DBport;
56 extern char *DBuser;
57 extern char *DBname;
58 extern char *DBpasswd;
59
60
61 /* authorise function takes the auth_vector, credentials struct, and 'overriden'
62 variable. If overriden == 1, then it immediately returns UP_AUTH_OK
63 (because this means that the update contained a valid override attribute).
64 Else, it goes through the auth_vector and when it finds a an "auth:"
65 attribute which passes, then it returns UP_AUTH_OK. Otherwise, it returns
66 UP_AUF (authorisation failed) */
67
68 int authorise(GSList * auth_vector, credentials_struct credentials, int overriden){
/* [<][>][^][v][top][bottom][index][help] */
69
70 int result = 0;
71
72 if(tracing){
73 printf("TRACING: authorise started with override: %i\n", overriden);
74 }
75
76 /* If 'overriden' variable is 1, then return UP_AUTH_OK immediately */
77 if(overriden == 1){
78 return UP_AUTH_OK;
79 }
80
81 else{
82 result = AU_authorise(auth_vector, credentials);
83 if(tracing){
84 printf("TRACING: authorise: AU_authorise returned %i\n", result);
85 }
86 if(result > 0){
87 return UP_AUTH_OK;
88 }
89 else{
90 return UP_AUF; /* authorisation failed */
91 }
92 }
93 }
94
95 /* concatanates the string at the end of error_msg */
96 void error_msg_cat(const char * string){
/* [<][>][^][v][top][bottom][index][help] */
97
98 if(string == NULL){
99 return;
100 }
101 if(error_msg == NULL){
102 error_msg = strdup(string);
103 }else{
104 error_msg = (char *)realloc(error_msg, strlen(error_msg) + strlen(string) + 2);
105 error_msg = strcat(error_msg, "\n");
106 error_msg = strcat(error_msg, string);
107 }
108 }
109
110
111 /* interprets the result string coming from RIPupd
112 It is called by send_object_db.
113 It returns the error no returned from RIPupd. */
114
115 int interpret_ripdb_result(const char * string){
/* [<][>][^][v][top][bottom][index][help] */
116 char * error_no = NULL;
117 char ** temp = NULL, ** temp2 = NULL;
118 int i;
119 int err = 0;
120
121 /* if the string is NULL or empty, then return error */
122 if(string == NULL || strlen(string) == 0){
123 error = UP_INT; /* internal error, RIPupd should return something */
124 error_msg_cat("Internal error. RIPupd didn't return anything.");
125 return 0;
126 }
127
128 /* split the string into lines */
129 temp = g_strsplit(string , "\n", 0);
130 for(i = 0; temp[i] != NULL; i++){
131 if(i == 0){/* this line must contain "%ERROR " string in the beginning */
132 temp2 = g_strsplit(temp[0], " ", 0);
133 error_no = strdup(temp2[1]);
134 g_strfreev(temp2);
135 err = atoi(error_no);
136 if(tracing){
137 printf("TRACING: interpret_ripdb_result: error_no is [%s]\n", error_no);
138 }
139 }else if(error_no != NULL && strcmp(error_no, "0") != 0){
140 error_msg_cat(temp[i]);
141 }
142 }
143 g_strfreev(temp);
144 if(error_no != NULL){
145 free(error_no);
146 }
147 return err; /* 0 means no error in this context */
148 }
149
150
151
152 /* Gets assigned NIC hdl from the string that is returned from
153 RIPupdate */
154 void get_assigned_nic(char * nic_hdl, const char * string){
/* [<][>][^][v][top][bottom][index][help] */
155 char * error_no = NULL;
156 char ** temp = NULL, ** temp2 = NULL;
157 int i;
158
159 /* if the string is NULL or empty, then return error */
160 if(string == NULL || strlen(string) == 0){
161 error = UP_INT; /* internal error, RIPupd should return something */
162 error_msg_cat("Internal error. RIPupd didn't return anything.");
163 return;
164 }
165
166 /* split the string into lines */
167 temp = g_strsplit(string , "\n", 0);
168 for(i = 0; temp[i] != NULL; i++){
169 if(i == 0){/* this line must contain "%ERROR " string in the beginning */
170 temp2 = g_strsplit(temp[0], " ", 0);
171 error_no = strdup(temp2[1]);
172 g_strfreev(temp2);
173 if(tracing){
174 printf("TRACING: get_assigned_nic: error_no is [%s]\n", error_no);
175 }
176 }else if(error_no != NULL && strcmp(error_no, "0") != 0){
177 error_msg_cat(temp[i]);
178 }else if(error_no != NULL && strcmp(error_no, "0") == 0 && i == 1){/* look for assigned NIC hdl */
179 /* in the second line RIPupdate returns for example "I[65][EK3-RIPE]" We
180 need to extract EK3-RIPE part */
181 //to_be_returned = (char *)malloc(128); /* 128 should be enough for a NIC hdl */
182 nic_hdl = strncpy(nic_hdl, rindex(temp[i],'[') + 1 ,
183 rindex(temp[i],']') - rindex(temp[i],'[') - 1);
184 nic_hdl[rindex(temp[i],']') - rindex(temp[i],'[') - 1] = '\0';
185 if(tracing && nic_hdl != NULL){
186 printf("TRACING: get_assigned_nic will return [%s]\n", nic_hdl);
187 }
188 g_strfreev(temp);
189 return;
190 }
191 }
192 g_strfreev(temp);
193 if(error_no != NULL && error_msg != NULL){
194 printf("TRACING: interpret_ripdb_result: Error: [%s][%s]\n", error_no, error_msg);
195 }
196 return;
197 }
198
199
200
201
202
203
204 /* strips lines beginning with "override:" off */
205 char * delete_override(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
206
207 char ** temp = NULL;
208 char * string = NULL;
209 int i;
210
211 if(arg == NULL){
212 return NULL;
213 }
214
215 /* split the string into lines */
216 temp = g_strsplit (arg, "\n", 0);
217
218 for(i=0; temp[i] != NULL; i++){
219 /* if the line begins with "override:", then do not copy it */
220 if(strstr(temp[i], "override:") != temp[i]){
221 if(string == NULL){
222 string = strdup(temp[i]);
223 }else{
224 string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
225 string = strcat(string, "\n");
226 string = strcat(string, temp[i]);
227 }
228 }
229 }
230 g_strfreev(temp);
231 return string;
232 }
233
234
235
236
237
238 /* Obtains a transaction ID for an object. Will be called from send_object_db */
239 int up_get_transaction_id(){
/* [<][>][^][v][top][bottom][index][help] */
240
241 SQ_connection_t * sql_connection;
242 SQ_result_set_t *result;
243 int error;
244 long new_id;
245
246 sql_connection = SQ_get_connection(DBhost, DBport, DBname, DBuser, DBpasswd);
247 if(!sql_connection){
248 fprintf(stderr, "No SQL connection\n");
249 exit(1);
250 }
251 error = SQ_execute_query(sql_connection, "INSERT INTO tid VALUES(NULL)", &result);
252 if(error){
253 fprintf(stderr,"ERROR: %s\n", SQ_error(sql_connection));
254 exit(1);
255 }
256
257 new_id = mysql_insert_id(sql_connection);
258
259 SQ_close_connection(sql_connection);
260
261 return new_id;
262 }
263
264
265
266
267
268
269 /* sends the object to the database. char * operation is either 'ADD' ,'DEL' or 'UPD'
270 assigned_NIC is filled in if this is a person/role creation with AUTO nic hdl
271 assigned_NIC must be allocated enough memory before send_object_db is called
272
273 If the called do not expect a NIC hdl back, then assigned_NIC can be given NULL
274 */
275 int send_object_db(char * arg, char * assigned_NIC, char * operation){
/* [<][>][^][v][top][bottom][index][help] */
276
277 int sockfd, numbytes;
278 char buf[MAXDATASIZE + 1];
279 struct hostent *he;
280 struct sockaddr_in their_addr; /* connector's address information */
281 char *result_string = NULL;
282 char *to_be_returned = NULL;
283 int err = 0;
284 char *to_be_sent = NULL;
285 int tr_id;
286 char * tr_id_str;
287
288 to_be_sent = delete_override(arg);
289
290 /* get the transaction ID, to be sent to RIPupdate*/
291 tr_id = up_get_transaction_id();
292
293 /* convert it into a string */
294 tr_id_str = (char *)malloc(64);
295 sprintf(tr_id_str, "%d", tr_id);
296
297 if ((he=gethostbyname(update_host)) == NULL) { /* get the host info */
298 perror("gethostbyname");
299 exit(1);
300 }
301
302 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
303 perror("socket");
304 exit(1);
305 }
306
307 their_addr.sin_family = AF_INET; /* host byte order */
308 their_addr.sin_port = htons(update_port); /* short, network byte order */
309 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
310 bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
311
312
313 if (connect(sockfd, (struct sockaddr *)&their_addr,
314 sizeof(struct sockaddr)) == -1) {
315 perror("connect");
316 exit(1);
317 }
318
319 if (send(sockfd, operation , strlen(operation), 0) == -1)
320 perror("send");
321 if (send(sockfd, " ", strlen(" "), 0) == -1)
322 perror("send");
323 if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
324 perror("send");
325 if (send(sockfd, "\n\n" , strlen("\n\n"), 0) == -1)
326 perror("send");
327 if (send(sockfd, arg , strlen(to_be_sent), 0) == -1)
328 perror("send");
329 if (send(sockfd, "\n\n", 2, 0) == -1)
330 perror("send");
331 /* send the ACK now */
332 if (send(sockfd, "ACK ",strlen("ACK "), 0) == -1)
333 perror("send");
334 if (send(sockfd, tr_id_str, strlen(tr_id_str), 0) == -1)
335 perror("send");
336 if (send(sockfd, "\n\n",strlen("\n\n"), 0) == -1)
337 perror("send");
338
339
340 while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
341 buf[numbytes] = '\0';
342 if(tracing){
343 printf("%s",buf);
344 }
345 if(result_string == NULL){
346 result_string = strdup(buf);
347 }else{
348 result_string = (char *)realloc(result_string,
349 strlen(result_string) + strlen(buf) + 1);
350 result_string = strcat(result_string, buf);
351 }
352 if(strstr(result_string,"\n\n") != NULL){/* if the result_string contains
353 an empty line at the end, we will close */
354 break;
355 };
356 }
357
358 err = interpret_ripdb_result(result_string);
359 if(assigned_NIC != NULL){ /* if the caller of the function expected to get a NIC handle */
360 get_assigned_nic(assigned_NIC, result_string);
361 }
362 close(sockfd);
363 free(to_be_sent);
364 return err; /* 0 means no error in this context */
365 }
366
367
368
369
370
371
372 /* takes a pre-parsed object, and returns its type */
373 char * get_class_type(Object *arg){
/* [<][>][^][v][top][bottom][index][help] */
374
375 char * be_returned = NULL;
376 if(arg == NULL) return NULL;
377 be_returned = strdup(arg->type->getName());
378 return g_strstrip(be_returned);
379 }
380
381
382
383
384
385
386 /* takes an object (pre-parsed) and returns its first attrib if it is not
387 a person, and returns the nic-hdl if it is a person object */
388 char * get_search_key(Object *arg, char * type, const char * text){
/* [<][>][^][v][top][bottom][index][help] */
389
390
391 Attr *attr;
392 char *primary_key = NULL, *value = NULL;
393
394 if(arg == NULL) return NULL;
395
396 for(attr = arg->attrs.head(); attr; attr = arg->attrs.next(attr)){
397 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
398 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
399 attr->len - strlen(attr->type->name()) -2 );
400 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
401 if(strcmp(attr->type->name(),type) == 0 &&
402 strcmp(type,"person") != 0 && strcmp(type,"role") != 0 ){
403 primary_key = strdup(value);
404 }
405 if(strcmp(attr->type->name(),"nic-hdl") == 0 &&
406 (strcmp(type,"person") == 0 || strcmp(type,"role") == 0 )){
407 primary_key = strdup(value);
408 }
409 free(value);
410 }
411 if(primary_key != NULL){
412 return g_strstrip(primary_key);
413 }else{
414 return NULL;
415 }
416 }
417
418
419
420
421 /* sends char * arg to the specified host's specified port, and
422 returns the reply as a string. This is used to query the
423 whois host. Probably we must use WC (whois client) module here,
424 but it must be extented */
425 char * send_and_get(char * host, int port, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
426
427 int sockfd, numbytes;
428 char * result = NULL;
429 char buf[MAXDATASIZE + 1];
430 struct hostent *he;
431 struct sockaddr_in their_addr; /* connector's address information */
432
433 if(tracing) {
434 printf("TRACING: send_and_get: arg : [%s]; port: [%i]; host: [%s]\n", arg, port, host);
435 }
436
437 if ((he=gethostbyname(host)) == NULL) { /* get the host info */
438 perror("gethostbyname");
439 exit(1);
440 }
441
442 if(tracing) {
443 printf("TRACING: send_and_get: called gethostbyname\n");
444 }
445
446 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
447 perror("socket");
448 exit(1);
449 }
450
451 if(tracing) {
452 printf("TRACING: send_and_get: called socket\n");
453 }
454
455
456 their_addr.sin_family = AF_INET; /* host byte order */
457 their_addr.sin_port = htons(port); /* short, network byte order */
458 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
459 bzero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
460
461 if (connect(sockfd, (struct sockaddr *)&their_addr,
462 sizeof(struct sockaddr)) == -1) {
463 perror("connect");
464 exit(1);
465 }
466 if (send(sockfd, arg , strlen(arg), 0) == -1)
467 perror("send");
468 if (send(sockfd, "\n",1,0) == -1)
469 perror("send");
470
471
472 while ((numbytes=recv(sockfd, buf, MAXDATASIZE, 0)) != 0) {
473 buf[numbytes] = '\0';
474 if(result == NULL){
475 result = strdup(buf);
476 }else{
477 result = (char *)realloc(result, strlen(result) + strlen(buf) + 1);
478 result = strcat(result, buf);
479 }
480 }
481
482 close(sockfd);
483 return result;
484
485
486 }
487
488
489
490 /* counts the number of objects in a string */
491 int count_objects(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
492 int count = 0;
493 char *pos = NULL;
494 char *temp = NULL;
495
496 if(tracing) {
497 printf("TRACING: count_objects running\n");
498 }
499
500 if(arg != NULL){
501 temp = strdup(arg);
502 }else{
503 return 0;
504 }
505
506 if(isalpha(arg[0])){
507 count++;
508 }else if(arg[0] == '\n' && isalpha(arg[1])){
509 count++;
510 }
511 while(pos = strstr(temp,"\n\n")){
512 pos[0] = 'a'; /* something non-EOL so that it won't be caught in the next loop */
513 if(isalpha(pos[2])){
514 count++;
515 }
516 }
517 if(tracing) {
518 cout << "TRACING: count_objects returning " << count << endl;
519 }
520 free(temp);
521 return count;
522 }
523
524
525 /* strips lines beginning with '%' off */
526 char * strip_lines(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
527
528 char ** temp = NULL;
529 char * string = NULL;
530 int i;
531
532 if(arg == NULL){
533 return NULL;
534 }
535
536 /* split the string into lines */
537 temp = g_strsplit (arg, "\n", 0);
538
539 for(i=0; temp[i] != NULL; i++){
540 if(temp[i][0] != '%'){
541 if(string == NULL){
542 string = strdup(temp[i]);
543 }else{
544 string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
545 string = strcat(string, "\n");
546 string = strcat(string, temp[i]);
547 }
548 }
549 }
550 return string;
551 }
552
553 /* Separates the objects in the given char * arg using "\n\n" as
554 separator. Returns a linked list whose data consist of separated
555 objects as char * */
556
557 GSList * take_objects(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
558 char ** objects=NULL;
559 char ** temp = NULL;
560 GSList * tobereturned = NULL;
561 int i;
562
563 arg = strip_lines(arg);
564
565 objects = g_strsplit(arg, "\n\n", 1000);
566 temp = objects;
567 for(i=0; temp[i] != NULL; i++){
568 /* stripe off the trailing and leading white spaces-eols*/
569 g_strstrip(temp[i]);
570 if(strlen(temp[i]) > 0){/* if not an empty string */
571 tobereturned = g_slist_append(tobereturned, temp[i]);
572 }
573 }
574 return tobereturned;
575 }
576
577
578
579
580
581 /* takes the first object in the given char *, using empty lines as
582 separator */
583 char * take_object(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
584 GSList * objects;
585 char * object;
586
587 objects = take_objects(arg);
588 if(g_slist_length(objects) > 0){
589 object = strdup((char *)(g_slist_nth_data(objects, 0)));
590 }else{
591 return NULL;
592 }
593 g_slist_free(objects);
594 return object;
595
596 }
597
598
599
600
601
602 /* Takes an autnum_object, and returns the as-block containing this aut-num */
603 char * get_as_block(char *autnum_object){
/* [<][>][^][v][top][bottom][index][help] */
604 bool code;
605 char * search_key = NULL, * query_string = NULL;
606 char * result = NULL;
607 Object * o = new Object();
608
609 code = o->scan_silent(autnum_object, strlen(autnum_object));
610 search_key = get_search_key(o,"aut-num",autnum_object);
611
612 query_string = (char *)malloc(strlen("-Tas-block -r ")+strlen(search_key)+1);
613 sprintf(query_string, "-Tas-block -r %s",search_key);
614 result = send_and_get(query_host, query_port, query_string);
615 if(count_objects(result) == 0){
616 if(tracing){
617 cout << "No such as-block" << endl;
618 }
619 return NULL;
620 }else if(count_objects(result) > 1){
621 if(tracing){
622 cout << "More than one as-block returned" << endl;
623 }
624 return NULL;
625 }else{ /* count_objects(result) == 1 */
626 return take_object(result);
627 }
628
629 }
630
631
632 /* Takes a route_object, and returns the aut-num mentioned in origin
633 attribute of this route */
634 char * get_aut_num_object(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
635 bool code;
636 char * search_key = NULL, * query_string = NULL;
637 char * result = NULL;
638 Object * o = new Object();
639
640 code = o->scan_silent(route_object, strlen(route_object));
641 search_key = get_search_key(o,"origin",route_object);
642
643 query_string = (char *)malloc(strlen("-Taut-num -r ")+strlen(search_key)+1);
644 sprintf(query_string, "-Taut-num -r %s",search_key);
645 result = send_and_get(query_host, query_port, query_string);
646 if(count_objects(result) == 0){
647 if(tracing){
648 cout << "No such aut-num" << endl;
649 }
650 return NULL;
651 }else if(count_objects(result) > 1){
652 if(tracing){
653 cout << "More than one aut-num returned" << endl;
654 }
655 return NULL;
656 }else{ /* count_objects(result) == 1 */
657 return take_object(result);
658 }
659
660 }
661
662
663
664
665 /* Takes a domain_object, and returns the less specific domain of it */
666 char * get_less_specific_domain(char *domain_object){
/* [<][>][^][v][top][bottom][index][help] */
667 bool code;
668 char * search_key = NULL, * query_string = NULL;
669 char * result = NULL, * domain = NULL;
670 Object * o = new Object();
671 int i,j, length;
672 char * temp = NULL;
673 char ** splitted;
674
675 code = o->scan_silent(domain_object, strlen(domain_object));
676 domain = get_search_key(o,"domain",domain_object);
677
678 /* split the domain from its dots ('50' is the max # of pieces, this number is just arbitrary) */
679 splitted = g_strsplit((char *)strdup(domain), ".", 50);
680
681 for(i=1; splitted[i] != NULL; i++){
682 /* in the following for loop, we will construct the 'less spec' domains
683 to be looked up in the DB */
684 for(j=i; splitted[j] !=NULL; j++){
685 length = 0;
686 if(temp!=NULL){
687 length = strlen(temp);
688 }
689 temp = (char *)realloc(temp, length + strlen(splitted[j]) + 2);
690 if(j==i){
691 temp = (char *)strdup(splitted[j]);
692 }else{
693 sprintf(temp, "%s.%s", temp, splitted[j]);
694 }
695 }
696 query_string = (char *)malloc(strlen("-Tdomain -r -R ")+strlen(temp)+1);
697 sprintf(query_string, "-Tdomain -r -R %s", temp);
698 result = send_and_get(query_host, query_port, query_string);
699 if(count_objects(result) == 0){
700 }else if(count_objects(result) > 1){
701 if(tracing){
702 cout << "TRACING: get_less_specific_domain: More than one domains returned" << endl;
703 }
704 return NULL; /* error condition */
705 }else{ /* count_objects(result) == 1 */
706 return take_object(result);
707 }
708
709 }
710 /* release the memory allocated to **splitted */
711 for(i=0; splitted[i] != NULL; i++){
712 free(splitted[i]);
713 }
714 /* so, we couldn't find any 'less specific' domain */
715 return NULL;
716 }
717
718
719
720
721
722 /* Takes a hierarchical set_object, and returns the less specific set or auth-num of it
723 by striping down the object's name ( eg, for as35:rs-trial:rs-myset,
724 as35:rs-trial is tried ) */
725 char * get_less_specific_set(char *set_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
726 bool code;
727 char * search_key = NULL, * query_string = NULL;
728 char * result = NULL;
729 Object * o = new Object();
730 int i;
731
732 code = o->scan_silent(set_object, strlen(set_object));
733 search_key = get_search_key(o, type, set_object);
734 delete(o);
735
736 for(i = strlen(search_key) -1; i > -1; i--){
737 if(search_key[i] == ':'){
738 search_key[i] = '\0'; /* truncate the string */
739 break;
740 }
741 if(i == 0){/* if we've reached the beginning of the string
742 (this means there wasn't any ';' in the string) */
743 free(search_key);
744 search_key = NULL;
745 }
746 }
747 if( search_key == NULL || strlen(search_key) == 0){/* this mustn't happen in fact, since
748 we make sure that the name of the
749 set_object contains a ':' in a proper place */
750 return NULL;
751 }
752
753
754 query_string = (char *)malloc(strlen("-Taut-num,as-set,rtr-set,peering-set,filter-set -r ")+strlen(search_key)+1);
755 sprintf(query_string, "-Taut-num,as-set,rtr-set,peering-set,filter-set -r %s", search_key);
756 result = send_and_get(query_host, query_port, query_string);
757 if(count_objects(result) == 0){
758 cout << "No such object" << endl;
759 return NULL;
760 }else if(count_objects(result) > 1){
761 cout << "More than one objects returned" << endl;
762 return NULL;
763 }else{ /* count_objects(result) == 1 */
764 return take_object(result);
765 }
766
767 }
768
769
770
771
772
773
774
775 /* Takes an inetnum or inet6num object and returns one less specific of it */
776 char * get_less_specific(char *inetnum_object, char *type){
/* [<][>][^][v][top][bottom][index][help] */
777 bool code;
778 char * search_key = NULL, * query_string = NULL;
779 char * result = NULL;
780 Object * o = new Object();
781
782 code = o->scan_silent(inetnum_object, strlen(inetnum_object));
783 search_key = get_search_key(o, type, inetnum_object);
784
785 query_string = (char *)malloc(strlen("-Tinet6num -r -l ") + strlen(search_key) + 1);
786 sprintf(query_string, "-T%s -r -l %s",type, search_key);
787 result = send_and_get(query_host, query_port, query_string);
788 if(count_objects(result) == 0){
789 cout << "No such " << type << endl;
790 return NULL;
791 }else if(count_objects(result) > 1){
792 cout << "More than one " << type << " returned" << endl;
793 return NULL;
794 }else{ /* count_objects(result) == 1 */
795 return take_object(result);
796 }
797
798 }
799
800
801
802 /* Takes a route object and returns one less specific inetnum */
803 char * get_less_spec_inetnum(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
804 bool code;
805 char * search_key = NULL, * query_string = NULL;
806 char * result = NULL;
807 Object * o = new Object();
808
809 code = o->scan_silent(route_object, strlen(route_object));
810 search_key = get_search_key(o, "route", route_object);
811
812 query_string = (char *)malloc(strlen("-Tinetnum -r -l ") + strlen(search_key) + 1);
813 sprintf(query_string, "-Tinetnum -r -l %s", search_key);
814 result = send_and_get(query_host, query_port, query_string);
815 if(count_objects(result) == 0){
816 cout << "No such inetnum" << endl;
817 return NULL;
818 }else if(count_objects(result) > 1){
819 cout << "More than one inetnums returned" << endl;
820 return NULL;
821 }else{ /* count_objects(result) == 1 */
822 return take_object(result);
823 }
824
825 }
826
827
828 /* Takes a route object and returns exact match inetnum */
829 char * get_exact_match_inetnum(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
830 bool code;
831 char * search_key = NULL, * query_string = NULL;
832 char * result = NULL;
833 Object * o = new Object();
834
835 code = o->scan_silent(route_object, strlen(route_object));
836 search_key = get_search_key(o, "route", route_object);
837
838 query_string = (char *)malloc(strlen("-Tinetnum -r -x ") + strlen(search_key) + 1);
839 sprintf(query_string, "-Tinetnum -r -x %s", search_key);
840 result = send_and_get(query_host, query_port, query_string);
841 if(count_objects(result) == 0){
842 cout << "No such inetnum" << endl;
843 return NULL;
844 }else if(count_objects(result) > 1){
845 cout << "More than one inetnums returned" << endl;
846 return NULL;
847 }else{ /* count_objects(result) == 1 */
848 return take_object(result);
849 }
850
851 }
852
853
854
855 /* Takes a route object and returns exact matches of this route */
856 GSList * get_exact_match_routes(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
857 bool code;
858 char * search_key = NULL, * query_string = NULL;
859 char * result = NULL;
860 Object * o = new Object();
861
862 code = o->scan_silent(route_object, strlen(route_object));
863 search_key = get_search_key(o, "route", route_object);
864
865 query_string = (char *)malloc(strlen("-Troute -r -x ") + strlen(search_key) + 1);
866 sprintf(query_string, "-Troute -r -x %s", search_key);
867 result = send_and_get(query_host, query_port, query_string);
868 if(count_objects(result) == 0){
869 //cout << "get_exact_match_routes: No such route" << endl;
870 return NULL;
871 }else{ /* count_objects(result) == 1 */
872 return take_objects(result);
873 }
874
875 }
876
877
878
879 /* Takes a route object and returns (immediate) less specifics of this route */
880 GSList * get_less_spec_routes(char *route_object){
/* [<][>][^][v][top][bottom][index][help] */
881 bool code;
882 char * search_key = NULL, * query_string = NULL;
883 char * result = NULL;
884 Object * o = new Object();
885
886 code = o->scan_silent(route_object, strlen(route_object));
887 search_key = get_search_key(o, "route", route_object);
888
889 query_string = (char *)malloc(strlen("-Troute -r -l ") + strlen(search_key) + 1);
890 sprintf(query_string, "-Troute -r -l %s", search_key);
891 result = send_and_get(query_host, query_port, query_string);
892 if(count_objects(result) == 0){
893 cout << "get_less_spec_routes: No such route" << endl;
894 return NULL;
895 }else{ /* count_objects(result) == 1 */
896 return take_objects(result);
897 }
898
899 }
900
901
902
903 /* Gets an object as a string and returns its 'mnt-by' attributes as a
904 GSList (linked list) */
905 /* No need for this function any more in fact. 'get_attr_list' can be used instead.
906 All calls to get_mntners(object) must be converted into get_attr_list(object, "mnt-by") */
907
908 GSList *get_mntners(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
909 bool code;
910 Object * o;
911 Attr *attr;
912 char *value = NULL;
913 GSList *list_of_mntners = NULL;
914 char * object;
915
916 /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it.
917 (no harm in having more than one) */
918 object = (char *)malloc(strlen(arg) + 2);
919 sprintf(object, "%s\n", arg);
920
921 if(tracing) {
922 printf("TRACING: get_mntners is running\n");
923 }
924 o = new Object;
925 code = o->scan_silent(object,strlen(object));
926
927 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
928 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
929 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
930 attr->len - strlen(attr->type->name()) -2 );
931 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
932 if(strcmp(attr->type->name(),"mnt-by") == 0){
933 if(tracing) {
934 cout << "TRACING: get_mntners: adding " << g_strstrip(value) << endl;
935 }
936 list_of_mntners = g_slist_append(list_of_mntners, strdup(g_strstrip(value)));
937 }
938 free(value);
939 }
940
941 free(object);
942 return list_of_mntners;
943 }
944
945
946 /* Gets a preparsed object, its text and an attribute name. Returns a list of
947 attribute values */
948 GSList *get_attributes(Object * o, const char * attrib, const char * text){
/* [<][>][^][v][top][bottom][index][help] */
949
950 char * value = NULL;
951 Attr *attr;
952 GSList *list_of_attributes = NULL;
953
954
955 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
956 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
957 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
958 attr->len - strlen(attr->type->name()) -2 );
959 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
960 if(strcmp(attr->type->name(), attrib) == 0){
961 if(tracing) {
962 cout << "TRACING: get_attributes: adding " << g_strstrip(value) << endl;
963 }
964 list_of_attributes = g_slist_append(list_of_attributes, g_strstrip(value));
965 }
966 }
967
968
969 return list_of_attributes;
970 }
971
972
973 /* Gets a preparsed object, an attribute name. Returns the value of first occurence
974 of this attribute */
975 char *get_attribute(Object * o, const char * attrib, char * text){
/* [<][>][^][v][top][bottom][index][help] */
976
977 char * value = NULL;
978 Attr *attr;
979
980 if(tracing) {
981 printf("TRACING: get_attributes is running\n");
982 }
983
984 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
985 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
986 strncpy(value, (char *)(text+attr->offset) + strlen(attr->type->name())+1,
987 attr->len - strlen(attr->type->name()) -2 );
988 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
989 if(strcmp(attr->type->name(), attrib) == 0){
990 if(tracing) {
991 cout << "TRACING: get_attribute: will return " << value << endl;
992 }
993 return value;
994 }else{
995 free(value);
996 }
997 }
998
999 if(tracing) {
1000 printf("TRACING: get_attribute is returning\n");
1001 }
1002
1003 return NULL;
1004 }
1005
1006
1007
1008 /* Gets a GSList of strings and returns 1 if one of them starts with substr, 0 otherwise */
1009 int strstr_in_list(GSList * list, const char * substr){
/* [<][>][^][v][top][bottom][index][help] */
1010
1011 GSList * next = NULL;
1012 char * word;
1013
1014 if(tracing) {
1015 printf("TRACING: strstr_in_list is running\n");
1016 }
1017
1018 for( next = list; next != NULL ; next = g_slist_next(next) ){
1019 word = strdup((char *)next->data);
1020 g_strup(word);
1021 if(strstr(word, substr) == word){
1022 free(word);
1023 return 1;
1024 }
1025 free(word);
1026 }
1027 /* none of them matched, so return 0 */
1028 return 0;
1029 }
1030
1031
1032
1033
1034
1035 /* Gets a (maintainer) object as a string and returns its 'auth' attributes
1036 as a GSList (linked list) */
1037
1038 GSList *get_auths(char * object){
/* [<][>][^][v][top][bottom][index][help] */
1039 bool code;
1040 Object * o;
1041 Attr *attr;
1042 char *value = NULL;
1043 GSList *list_of_auths = NULL;
1044
1045 if(tracing){
1046 printf("TRACING: get_auths is running\n");
1047 }
1048 o = new Object;
1049 code = o->scan_silent(object,strlen(object));
1050
1051 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1052 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1053 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1054 attr->len - strlen(attr->type->name()) -2 );
1055 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1056 if(strcmp(attr->type->name(),"auth") == 0){
1057 if(tracing) {
1058 cout << "TRACING: get_auths: adding " << g_strstrip(value) << endl;
1059 }
1060 list_of_auths = g_slist_append(list_of_auths, strdup(g_strstrip(value)));
1061 if(tracing) {
1062 cout << "TRACING: get_auths: # of nodes in list_of_auths is now " << g_slist_length(list_of_auths) << endl;
1063 }
1064 }
1065 }
1066
1067 if(tracing) {
1068 cout << "TRACING: get_auths: returning (with " << g_slist_length(list_of_auths) << " nodes)" << endl;
1069 }
1070 return list_of_auths;
1071 }
1072
1073
1074
1075
1076 /* Gets an object as a string an returns its 'attr_type' attributes as a
1077 GSList (linked list) */
1078
1079 GSList *get_attr_list(char * arg, char * attr_type){
/* [<][>][^][v][top][bottom][index][help] */
1080 bool code;
1081 Object * o;
1082 Attr *attr;
1083 char *value = NULL;
1084 GSList *list_of_attrs = NULL;
1085 char * object;
1086
1087 /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it.
1088 (no harm in having more than one) */
1089 object = (char *)malloc(strlen(arg) + 2);
1090 sprintf(object, "%s\n", arg);
1091
1092 if(tracing) {
1093 printf("TRACING: get_attr_list is running, object is \n#%s#\n", object);
1094 }
1095 o = new Object;
1096 code = o->scan_silent(object,strlen(object));
1097
1098 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1099 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1100 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1101 attr->len - strlen(attr->type->name()) -2 );
1102 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1103 if(strcmp(attr->type->name(), attr_type) == 0){
1104 if(tracing) {
1105 cout << "TRACING: get_attr_list: adding " << g_strstrip(value) << endl;
1106 }
1107 list_of_attrs = g_slist_append(list_of_attrs, g_strstrip(value));
1108 }
1109 }
1110
1111 free(object);
1112 return list_of_attrs;
1113 }
1114
1115
1116
1117
1118
1119
1120 /* Gets an object as a string an returns its mnt_lower attributes as a
1121 GSList (linked list) */
1122
1123 GSList *get_mnt_lowers(char * object){
/* [<][>][^][v][top][bottom][index][help] */
1124 bool code;
1125 Object * o;
1126 Attr *attr;
1127 char *value = NULL;
1128 GSList *list_of_mnt_lowers = NULL;
1129
1130
1131 if(tracing) {
1132 printf("TRACING: get_mnt_lowers is running\n");
1133 }
1134 o = new Object;
1135 code = o->scan_silent(object,strlen(object));
1136
1137 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1138 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1139 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1140 attr->len - strlen(attr->type->name()) -2 );
1141 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1142 if(strcmp(attr->type->name(),"mnt-lower") == 0){
1143 if(tracing) {
1144 cout << "TRACING: get_mnt_lowers: adding " << g_strstrip(value) << endl;
1145 }
1146 list_of_mnt_lowers = g_slist_append(list_of_mnt_lowers, strdup(g_strstrip(value)));
1147 }
1148 }
1149
1150
1151 return list_of_mnt_lowers;
1152 }
1153
1154
1155 /* Gets an object as a string an returns its mnt_routes attributes as a
1156 GSList (linked list) */
1157
1158 GSList *get_mnt_routes(char * object){
/* [<][>][^][v][top][bottom][index][help] */
1159 bool code;
1160 Object * o;
1161 Attr *attr;
1162 char *value = NULL;
1163 GSList *list_of_mnt_routes = NULL;
1164
1165 if(tracing) {
1166 cout << "TRACING: get_mnt_routes is running" << endl;
1167 }
1168 o = new Object;
1169 code = o->scan_silent(object,strlen(object));
1170
1171 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1172 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1173 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1174 attr->len - strlen(attr->type->name()) -2 );
1175 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1176 if(strcmp(attr->type->name(),"mnt-routes") == 0){
1177 if(tracing) {
1178 cout << "TRACING: get_mnt_routes: adding " << g_strstrip(value) << endl;
1179 }
1180 list_of_mnt_routes = g_slist_append(list_of_mnt_routes, strdup(g_strstrip(value)));
1181 }
1182 }
1183
1184 return list_of_mnt_routes;
1185 }
1186
1187
1188 /* Gets a linked list of objects and returns the mnt_routes attribs of
1189 them in a linked list */
1190 GSList *get_mnt_routes_from_list(GSList * objects){
/* [<][>][^][v][top][bottom][index][help] */
1191 GSList *next = NULL;
1192 GSList *list_of_mnt_routes = NULL;
1193
1194 for( next = objects; next != NULL ; next = g_slist_next(next) ){
1195 list_of_mnt_routes = g_slist_concat(list_of_mnt_routes, get_mnt_routes((char *)next->data));
1196 }
1197
1198 return list_of_mnt_routes;
1199 }
1200
1201
1202
1203 /* Gets a linked list of objects and returns the mnt_routes attribs of
1204 them in a linked list */
1205 GSList *get_mnt_lowers_from_list(GSList * objects){
/* [<][>][^][v][top][bottom][index][help] */
1206 GSList *next = NULL;
1207 GSList *list_of_mnt_lowers = NULL;
1208
1209 for( next = objects; next != NULL ; next = g_slist_next(next) ){
1210 list_of_mnt_lowers = g_slist_concat(list_of_mnt_lowers, get_mnt_lowers((char *)next->data));
1211 }
1212
1213 return list_of_mnt_lowers;
1214 }
1215
1216
1217
1218 /* retrieves the override password from the 'override' attribute
1219 of the object. If none, it returns NULL */
1220 char *get_override(char * object){
/* [<][>][^][v][top][bottom][index][help] */
1221 bool code;
1222 Object * o;
1223 Attr *attr;
1224 char *value = NULL;
1225
1226 if(tracing){
1227 printf("TRACING: get_override is running\n");
1228 }
1229 o = new Object;
1230 code = o->scan_silent(object,strlen(object));
1231
1232 for(attr = o->attrs.head(); attr; attr = o->attrs.next(attr)){
1233 value = (char*)malloc((*attr).len - strlen(attr->type->name()) - 1);
1234 strncpy(value, (char *)(object+attr->offset) + strlen(attr->type->name())+1,
1235 attr->len - strlen(attr->type->name()) -2 );
1236 value[attr->len - strlen(attr->type->name()) - 2 ] = '\0';
1237 if(strcmp(attr->type->name(),"override") == 0){
1238 if(tracing) {
1239 cout << "TRACING: get_override: returning " << g_strstrip(value) << endl;
1240 }
1241 return strdup(g_strstrip(value));
1242 }
1243 }
1244 /* there was no 'override' attrib, so return NULL */
1245 return NULL;
1246 }
1247
1248
1249
1250
1251
1252
1253 /* checks override string (password)
1254 returns OVR_OK if it is correct password */
1255 int check_override(char * string){
/* [<][>][^][v][top][bottom][index][help] */
1256 char ** temp;
1257 int i;
1258 char * crypted_password = strdup(overridecryptedpw);
1259 if(string == NULL) {
1260 if(tracing) {
1261 printf("TRACING: check_override is returning FAILED\n");
1262 }
1263 return UP_OVF; /* override attempt failed */
1264 }else{
1265 /* split the string */
1266 temp = g_strsplit (string, " ", 0);
1267
1268 for(i=0; temp[i] != NULL; i++){
1269 if(strlen(temp[i]) != 0){
1270 if(strcmp(AU_crypt(temp[i], crypted_password), crypted_password) == 0){
1271 g_strfreev(temp);
1272 if(tracing) {
1273 printf("TRACING: check_override is returning OK\n", string);
1274 }
1275 return OVR_OK;
1276 }
1277 }
1278 }
1279
1280 g_strfreev(temp);
1281 /* we couldn't find a word matching the override password */
1282 return UP_OVF; /* override attempt failed */
1283 }
1284 }
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297 /* takes a GSList of struct auth_struct and a GSList of auths, and a mntner name,
1298 add new elements to GSList of struct auth_struct and returns the new
1299 GSList of struct auth_struct */
1300
1301 GSList * add_to_auth_vector(GSList * list_of_auth_struct, GSList * auths, char * mntner_name){
/* [<][>][^][v][top][bottom][index][help] */
1302 GSList * next;
1303 char * auth_attrib = NULL;
1304 char * auth_attrib_uppercase = NULL, * argument = NULL;
1305 auth_struct * temp = NULL;
1306 int index = 1;
1307
1308 for(next = auths; next != NULL; next = g_slist_next(next)){
1309 auth_attrib = strdup((char *)next->data);
1310 auth_attrib = g_strstrip(auth_attrib);
1311 if(tracing) {
1312 cout << "TRACING: add_to_auth_vector: " << auth_attrib << endl;
1313 }
1314 /* Take the auth attribute and convert it into uppercase for comparisons */
1315 auth_attrib_uppercase = strdup(auth_attrib);
1316 g_strup(auth_attrib_uppercase);
1317
1318 if(strstr(auth_attrib_uppercase,"CRYPT-PW") == auth_attrib_uppercase){
1319 /* take the argument of the auth attribute */
1320 argument = strdup(auth_attrib + strlen("CRYPT-PW"));
1321 g_strstrip(argument);
1322 if(tracing) {
1323 cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1324 }
1325 temp = (auth_struct *)malloc(sizeof(auth_struct));
1326 temp->type = AU_CRYPT_PW;
1327 temp->auth = argument;
1328 temp->mntner_name = mntner_name;
1329 temp->index = index++;
1330 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1331 }else if(strstr(auth_attrib_uppercase,"MAIL-FROM") == auth_attrib_uppercase){
1332 /* take the argument of the auth attribute */
1333 argument = strdup(auth_attrib + strlen("MAIL-FROM"));
1334 g_strstrip(argument);
1335 if(tracing) {
1336 cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1337 }
1338 temp = (auth_struct *)malloc(sizeof(auth_struct));
1339 temp->type = AU_MAIL_FROM;
1340 temp->auth = argument;
1341 temp->mntner_name = mntner_name;
1342 temp->index = index++;
1343 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1344 }else if(strstr(auth_attrib_uppercase,"NONE") == auth_attrib_uppercase){
1345 /* take the argument of the auth attribute */
1346 temp = (auth_struct *)malloc(sizeof(auth_struct));
1347 temp->type = AU_NONE;
1348 temp->auth = NULL;
1349 temp->mntner_name = mntner_name;
1350 temp->index = index++;
1351 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1352 }else if(strstr(auth_attrib_uppercase,"PGPKEY-") == auth_attrib_uppercase){
1353 argument = strdup(auth_attrib + strlen("PGPKEY-"));
1354 g_strstrip(argument);
1355 if(tracing) {
1356 cout << "TRACING: add_to_auth_vector: adding new argument: " << argument << endl;
1357 }
1358 temp = (auth_struct *)malloc(sizeof(auth_struct));
1359 temp->type = AU_PGP;
1360 temp->mntner_name = mntner_name;
1361 temp->index = index++;
1362 temp->auth = argument;
1363 list_of_auth_struct = g_slist_append(list_of_auth_struct, temp);
1364 }else{
1365 if(tracing){
1366 cout << "TRACING: Error: invalid auth attrib: " << auth_attrib << endl;
1367 }
1368 return NULL;
1369 }
1370 }
1371 free(auth_attrib_uppercase);
1372 free(auth_attrib);
1373 return list_of_auth_struct;
1374
1375 }
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385 /* Gets a list of mntner names, retrieves those mntners from
1386 the database and extracts the 'auth' attributes, and
1387 constructs the authorisation vector, which is a GSList of
1388 struct auth_struct */
1389
1390 GSList * get_auth_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1391 GSList * list_of_auths = NULL;
1392 GSList * next = NULL;
1393 GSList * to_be_returned = NULL;
1394 char * query_string = NULL, * result = NULL, * object = NULL;
1395 GSList * temp;
1396
1397 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1398 if(tracing) {
1399 cout << "=====" << endl << "Got a mntner" << endl;
1400 cout << (char *)next->data << endl;
1401 }
1402 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1403 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1404 result = send_and_get(query_host, query_port, query_string);
1405 if(count_objects(result) == 0){
1406 /* no such maintainer */
1407 return NULL;
1408 }else if(count_objects(result) > 1){
1409 if(tracing) {
1410 cout << "More than one objects returned" << endl;
1411 }
1412 }else{ /* count_objects(result) == 1 */
1413 object = take_object(result);
1414 if(tracing) {
1415 printf("TRACING: get_auth_vector: Calling get_auths(char *)\n");
1416 }
1417 temp = get_auths(object);
1418 if(tracing) {
1419 cout << "TRACING: get_auth_vector: get_auths(char *) returned (with " << g_slist_length(temp) << " nodes)" << endl;
1420 }
1421 list_of_auths = g_slist_concat(list_of_auths, temp);
1422 if(tracing) {
1423 cout << "TRACING: get_auth_vector: list_of_auths has now " << g_slist_length(list_of_auths) << " nodes" << endl;
1424 }
1425 /* add this to the auth_vector. ( next->data is the name of the maintainer ) */
1426 if(tracing) {
1427 cout << "TRACING: get_auth_vector: to_be_returned has now " << g_slist_length(to_be_returned) << " nodes" << endl;
1428 }
1429 to_be_returned = add_to_auth_vector(to_be_returned, list_of_auths, (char *)next->data);
1430 }
1431 }
1432
1433 if(tracing) {
1434 printf("TRACING: get_auth_vector: to_be_returned has %i nodes\n", g_slist_length(to_be_returned));
1435 }
1436 return to_be_returned;
1437 }
1438
1439
1440
1441
1442
1443
1444
1445 /* Gets a list of mntner names, retrieves those mntners from
1446 the database and extracts the 'mnt-by' attributes, and
1447 returns them as a GSList */
1448
1449 GSList * get_mntnfy_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1450 GSList * list_of_mntnfy = NULL;
1451 GSList * next = NULL;
1452 //GSList * to_be_returned = NULL;
1453 char * query_string = NULL, * result = NULL, * object = NULL;
1454 GSList * temp;
1455
1456 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1457 if(tracing) {
1458 cout << "=====" << endl << "Got a mntner" << endl;
1459 cout << (char *)next->data << endl;
1460 }
1461 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1462 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1463 result = send_and_get(query_host, query_port, query_string);
1464 if(count_objects(result) == 0){
1465 /* no such maintainer */
1466 }else if(count_objects(result) > 1){
1467 if(tracing) {
1468 cout << "More than one objects returned" << endl;
1469 }
1470 }else{ /* count_objects(result) == 1 */
1471 object = take_object(result);
1472 if(tracing) {
1473 printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1474 }
1475 temp = get_attr_list(object, "mnt-nfy");
1476 if(tracing) {
1477 cout << "TRACING: get_mntnfy_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1478 }
1479 list_of_mntnfy = g_slist_concat(list_of_mntnfy, temp);
1480 if(tracing) {
1481 cout << "TRACING: get_mntnfy_vector: list_of_mntnfy has now " << g_slist_length(list_of_mntnfy) << " nodes" << endl;
1482 }
1483 }
1484 }
1485
1486 if(tracing) {
1487 printf("TRACING: get_auth_vector: list_of_mntnfy has %i nodes\n", g_slist_length(list_of_mntnfy));
1488 }
1489 return list_of_mntnfy;
1490 }
1491
1492
1493
1494
1495
1496
1497 /* Gets a list of mntner names, retrieves those mntners from
1498 the database and extracts the 'upd-to' attributes, and
1499 returns them as a GSList */
1500
1501 GSList * get_updto_vector(GSList * mntners){
/* [<][>][^][v][top][bottom][index][help] */
1502 GSList * list_of_updto = NULL;
1503 GSList * next = NULL;
1504 char * query_string = NULL, * result = NULL, * object = NULL;
1505 GSList * temp;
1506
1507 for( next = mntners; next != NULL ; next = g_slist_next(next) ){
1508 if(tracing) {
1509 cout << "=====" << endl << "Got a mntner" << endl;
1510 cout << (char *)next->data << endl;
1511 }
1512 query_string = (char *)malloc(strlen("-Tmntner -r ")+strlen((char *)next->data)+1);
1513 sprintf(query_string, "-Tmntner -r %s",(char *)next->data);
1514 result = send_and_get(query_host, query_port, query_string);
1515 if(count_objects(result) == 0){
1516 /* no such maintainer */
1517 }else if(count_objects(result) > 1){
1518 if(tracing) {
1519 cout << "More than one objects returned" << endl;
1520 }
1521 }else{ /* count_objects(result) == 1 */
1522 object = take_object(result);
1523 if(tracing) {
1524 printf("TRACING: get_mntnfy_vector: Calling get_attr_list\n");
1525 }
1526 temp = get_attr_list(object, "upd-to");
1527 if(tracing) {
1528 cout << "TRACING: get_updto_vector: get_attr_list returned (with " << g_slist_length(temp) << " nodes)" << endl;
1529 }
1530 list_of_updto = g_slist_concat(list_of_updto, temp);
1531 if(tracing) {
1532 cout << "TRACING: get_updto_vector: list_of_mntnfy has now " << g_slist_length(list_of_updto) << " nodes" << endl;
1533 }
1534 }
1535 }
1536
1537 if(tracing) {
1538 printf("TRACING: get_updto_vector: list_of_updto has %i nodes\n", g_slist_length(list_of_updto));
1539 }
1540 return list_of_updto;
1541 }
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552 /* gets one or more route objects filters out the ones which don't have the same
1553 origin as 'char * origin' argument */
1554 char * filter_out_diff_origins(char * objects, char * origin){
/* [<][>][^][v][top][bottom][index][help] */
1555 GSList * object_list = NULL, * next =NULL;
1556 char * objects_to_be_returned = NULL;
1557 bool code;
1558 char * key = NULL;
1559 Object * o = new Object();
1560
1561
1562 if(tracing) {
1563 printf("TRACING: filter_out_diff_origins\n");
1564 }
1565
1566 /* strip the lines beginning with '%' off */
1567 objects = strip_lines(objects);
1568
1569 /* separate the objects, store them in a linked list */
1570 object_list = take_objects(objects);
1571
1572 for(next = object_list; next != NULL; next = g_slist_next(next)){
1573 code = o->scan_silent((char *)next->data, strlen((char *)next->data));
1574 key = get_search_key(o, "origin", (char *)next->data);
1575 if(key != NULL && strcasecmp(g_strstrip(origin), key) == 0){
1576 if(objects_to_be_returned == NULL){
1577 objects_to_be_returned = strdup((char *)next->data);
1578 }else{
1579 objects_to_be_returned = (char *)realloc(objects_to_be_returned,
1580 strlen(objects_to_be_returned) + strlen((char *)next->data) + 2);
1581 objects_to_be_returned = strcat(objects_to_be_returned, "\n");
1582 objects_to_be_returned = strcat(objects_to_be_returned, (char *)next->data);
1583 }
1584 }
1585 }
1586
1587 delete(o);
1588 if(tracing) {
1589 if(objects_to_be_returned != NULL){
1590 printf("TRACING: filter_out_diff_origins: returning:\n%s\n", objects_to_be_returned? "(NULL)":objects_to_be_returned);
1591 }else {
1592 printf("TRACING: filter_out_diff_origins: returning NULL\n");
1593
1594 }
1595 }
1596 return objects_to_be_returned;
1597
1598 }
1599
1600
1601
1602
1603 /* Check authorisation
1604 Applies authorisation rules according to the object type
1605
1606 Arguments:
1607 char *new_object: the new object,
1608 char *old_object: the old object, as found in the database,
1609 char *type: type of the object
1610 credentials_struct credentials: a struct which
1611 contains credentials of the update, such as 'From:' field of
1612 the e-mail header and passwords in the update */
1613
1614 int check_auth(char *new_object, char *old_object, char *type, credentials_struct credentials){
/* [<][>][^][v][top][bottom][index][help] */
1615
1616 GSList *old_mntners = NULL, *new_mntners = NULL;
1617 GSList *old_auths = NULL, *new_auths = NULL;
1618 GSList *as_block_mnt_lowers = NULL;
1619 GSList *old_auth_vector = NULL, *new_auth_vector = NULL, *as_block_auth_vector = NULL;
1620 GSList *less_specific_auth_vector = NULL, *less_specific_mnt_lowers = NULL;
1621 GSList *less_specific_mntners = NULL;
1622 GSList *aut_num_maintainers = NULL;
1623 GSList *aut_num_auth_vector = NULL;
1624 GSList *exact_match_routes = NULL;
1625 GSList *exact_match_routes_maintainers = NULL;
1626 GSList *exact_match_routes_auth_vector = NULL;
1627 GSList *less_spec_routes = NULL;
1628 GSList *less_spec_routes_mntners = NULL;
1629 GSList *less_spec_routes_auth_vector = NULL;
1630 GSList *exact_match_inetnum_mnt_routes = NULL;
1631 GSList *exact_match_inetnum_auth_vector = NULL;
1632 GSList *less_spec_inetnum_mntners = NULL;
1633 GSList *less_spec_inetnum_auth_vector = NULL;
1634 GSList *exact_match_intenum_auth_vector = NULL;
1635 GSList *exact_match_auth_vector = NULL;
1636
1637 char *as_block_object = NULL, *less_specific_object = NULL;
1638 char *less_specific_domain = NULL;
1639 char *less_spec_inetnum = NULL;
1640 char *exact_match_inetnum = NULL;
1641 char *less_specific_object_type = NULL;
1642 char *override_string = NULL;
1643 char *set_name = NULL;
1644 char * aut_num_object = NULL;
1645 Object *set_object = new Object();
1646 Object *temp_obj;
1647 bool code;
1648 bool aut_num_auth_OK = false;
1649
1650 int overriden = 0;
1651
1652 /* first check if it is overriden or not. if overriden, check the override
1653 password. If it is correct, continue, setting "overriden" to 1. If not,
1654 immediately exit returning ERR_UP_OVF */
1655 override_string = get_override((new_object == NULL) ? old_object : new_object );
1656 if(override_string == NULL){
1657 overriden = 0;
1658 }else if(check_override(override_string) == OVR_OK){
1659 overriden = 1; /* authorisation is overriden */
1660 free(override_string);override_string = NULL;
1661 }else if(check_override(override_string) == UP_OVS){
1662 free(override_string);override_string = NULL;
1663 return UP_OVS; /* override syntax error --it must have at least two words */
1664 }else{
1665 free(override_string);override_string = NULL;
1666 return UP_OVF; /* override failed! */
1667 }
1668
1669
1670 /*
1671 * Handle the "person", "role", "limerick", "inet-rtr", "key-cert" types
1672 */
1673 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0 ||
1674 strcmp(type,"limerick") == 0 || strcmp(type,"inet-rtr") == 0 ||
1675 strcmp(type,"key-cert") == 0 ){
1676 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1677 old_mntners = get_mntners(old_object);
1678 old_auth_vector = get_auth_vector(old_mntners);
1679 return authorise(old_auth_vector, credentials, overriden);
1680 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1681 new_mntners = get_mntners(new_object);
1682 new_auth_vector = get_auth_vector(new_mntners);
1683 if(new_mntners != NULL && new_auth_vector == NULL){
1684 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1685 return UP_AUF; /* auth failed */
1686 }
1687 return authorise(new_auth_vector, credentials, overriden);
1688 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1689 old_mntners = get_mntners(old_object);
1690 old_auth_vector = get_auth_vector(old_mntners);
1691 if(old_mntners != NULL && old_auth_vector == NULL){
1692 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1693 return UP_AUF; /* auth failed */
1694 }
1695 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1696 return authorise(old_auth_vector, credentials, overriden);
1697 }else{
1698 new_mntners = get_mntners(new_object);
1699 new_auth_vector = get_auth_vector(new_mntners);
1700 if(new_mntners != NULL && new_auth_vector == NULL){
1701 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1702 return UP_AUF; /* auth failed */
1703 }
1704 return authorise(new_auth_vector, credentials, overriden);
1705 }
1706 }else{ // both are NULL, mustn't happen
1707 if(tracing){
1708 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1709 }
1710 return UP_INT; /* internal error */
1711 }
1712 }
1713
1714 /*
1715 * Handle the "aut-num" type
1716 */
1717 else if(strcmp(type,"aut-num") == 0 ){
1718 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1719 old_mntners = get_mntners(old_object);
1720 old_auth_vector = get_auth_vector(old_mntners);
1721 if(old_mntners != NULL && old_auth_vector == NULL){
1722 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1723 return UP_AUF; /* auth failed */
1724 }
1725 return authorise(old_auth_vector, credentials, overriden);
1726 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1727 as_block_object = get_as_block(new_object);
1728 if(as_block_object == NULL ){
1729 return UP_ABN; /* As-block does not exist */
1730 }else{
1731 as_block_mnt_lowers = get_mnt_lowers(as_block_object);
1732 as_block_auth_vector = get_auth_vector(as_block_mnt_lowers);
1733 if(as_block_mnt_lowers != NULL && as_block_auth_vector == NULL){
1734 /* then, the mntners in 'as_block_mnt_lowers' do not exist. Problem. */
1735 return UP_AUF; /* auth failed */
1736 }
1737 if(authorise(as_block_auth_vector, credentials, overriden) == UP_AUTH_OK ){
1738 new_mntners = get_mntners(new_object);
1739 new_auth_vector = get_auth_vector(new_mntners);
1740 if(new_mntners != NULL && new_auth_vector == NULL){
1741 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
1742 return UP_AUF; /* auth failed */
1743 }
1744 return authorise(new_auth_vector, credentials, overriden);
1745 }else{
1746 return UP_HOF; /* hierarchical auth failed */
1747 }
1748 }
1749 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1750 old_mntners = get_mntners(old_object);
1751 old_auth_vector = get_auth_vector(old_mntners);
1752 if(old_mntners != NULL && old_auth_vector == NULL){
1753 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1754 return UP_AUF; /* auth failed */
1755 }
1756 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1757 return authorise(old_auth_vector, credentials, overriden);
1758 }else{
1759 new_mntners = get_mntners(new_object);
1760 new_auth_vector = get_auth_vector(new_mntners);
1761 if(new_mntners != NULL && new_auth_vector == NULL){
1762 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1763 return UP_AUF; /* auth failed */
1764 }
1765 return authorise(new_auth_vector, credentials, overriden);
1766 }
1767 }else{ /* both are NULL, mustn't happen */
1768 if(tracing) {
1769 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1770 }
1771 return UP_INT; /* internal error */
1772 }
1773 }
1774
1775 /*
1776 * Handle the "mntner/as-block" types
1777 */
1778 else if(strcmp(type,"mntner") == 0 || strcmp(type,"as-block") == 0 ){
1779 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1780 old_mntners = get_mntners(old_object);
1781 old_auth_vector = get_auth_vector(old_mntners);
1782 if(old_mntners != NULL && old_auth_vector == NULL){
1783 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1784 return UP_AUF; /* auth failed */
1785 }
1786 return authorise(old_auth_vector, credentials, overriden);
1787 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1788 if(overriden || test_mode){
1789 return UP_AUTH_OK;
1790 }else{/* If not overriden, must be forwarded to <HUMAILBOX> */
1791 if(tracing) {
1792 cout << "TRACING: check_auth: '" << type << "' creation requested" << endl;
1793 }
1794 return UP_FWD; /* must be forwarded to <HUMAILBOX> */
1795 }
1796 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1797 old_mntners = get_mntners(old_object);
1798 old_auth_vector = get_auth_vector(old_mntners);
1799 if(old_mntners != NULL && old_auth_vector == NULL){
1800 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1801 return UP_AUF; /* auth failed */
1802 }
1803 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1804 return authorise(old_auth_vector, credentials, overriden);
1805 }else{
1806 new_mntners = get_mntners(new_object);
1807 new_auth_vector = get_auth_vector(new_mntners);
1808 if(new_mntners != NULL && new_auth_vector == NULL){
1809 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1810 return UP_AUF; /* auth failed */
1811 }
1812 return authorise(new_auth_vector, credentials, overriden);
1813 }
1814 }else{ // both are NULL, mustn't happen
1815 if(tracing){
1816 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1817 }
1818 return UP_INT; /* internal error */
1819 }
1820 }
1821
1822 /*
1823 * Handle the "inetnum/inet6num" types
1824 */
1825 else if(strcmp(type,"inetnum") == 0 || strcmp(type,"inet6num") == 0 ){
1826 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1827 old_mntners = get_mntners(old_object);
1828 old_auth_vector = get_auth_vector(old_mntners);
1829 if(old_mntners != NULL && old_auth_vector == NULL){
1830 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1831 return UP_AUF; /* auth failed */
1832 }
1833 return authorise(old_auth_vector, credentials, overriden);
1834 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1835 less_specific_object = get_less_specific(new_object, type);
1836 if(less_specific_object == NULL){
1837 if(overriden){
1838 return UP_AUTH_OK;
1839 }else{
1840 return UP_HOF; /* hierarchical authorisation failed */
1841 }
1842 }else{ /* if we got an inet(6)num object */
1843 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
1844 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1845 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1846 /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1847 return UP_AUF; /* auth failed */
1848 }
1849 if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1850 new_mntners = get_mntners(new_object);
1851 new_auth_vector = get_auth_vector(new_mntners);
1852 if(new_mntners != NULL && new_auth_vector == NULL){
1853 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1854 return UP_AUF; /* auth failed */
1855 }
1856 return authorise(new_auth_vector, credentials, overriden);
1857 }else{
1858 return UP_HOF; /* hierarchical authorisation failed */
1859 }
1860 }
1861 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1862 old_mntners = get_mntners(old_object);
1863 old_auth_vector = get_auth_vector(old_mntners);
1864 if(old_mntners != NULL && old_auth_vector == NULL){
1865 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1866 return UP_AUF; /* auth failed */
1867 }
1868 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1869 return authorise(old_auth_vector, credentials, overriden);
1870 }else{
1871 new_mntners = get_mntners(new_object);
1872 new_auth_vector = get_auth_vector(new_mntners);
1873 if(new_mntners != NULL && new_auth_vector == NULL){
1874 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1875 return UP_AUF; /* auth failed */
1876 }
1877 return authorise(new_auth_vector, credentials, overriden);
1878 }
1879 }else{ /* both are NULL, mustn't happen */
1880 if(tracing){
1881 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1882 }
1883 return UP_INT; /* internal error */
1884 }
1885 }
1886
1887
1888
1889 /*
1890 * Handle the "domain" type
1891 */
1892 else if(strcmp(type,"domain") == 0){
1893 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1894 old_mntners = get_mntners(old_object);
1895 old_auth_vector = get_auth_vector(old_mntners);
1896 if(old_mntners != NULL && old_auth_vector == NULL){
1897 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1898 return UP_AUF; /* auth failed */
1899 }
1900 return authorise(old_auth_vector, credentials, overriden);
1901 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1902 /* now, we have to find a 'less specific domain object' for this.
1903 If there is no less specific object, then creation is possible
1904 only with overriding. */
1905 less_specific_domain = get_less_specific_domain(new_object);
1906 if(less_specific_domain == NULL){
1907 if(overriden){/* we didn't get a 'less specific' domain object */
1908 return UP_AUTH_OK;
1909 }else{
1910 return UP_HOF; /* hierarchical authorisation failed */
1911 }
1912 }else{ /* we get a 'less specific' domain object */
1913 less_specific_mnt_lowers = get_mnt_lowers(less_specific_domain);
1914 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
1915 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
1916 /* then, the mntners in 'less_specific_mnt_lowers' do not exist. Problem. */
1917 return UP_AUF; /* auth failed */
1918 }
1919 if(authorise(less_specific_auth_vector, credentials, overriden) == UP_AUTH_OK){
1920 new_mntners = get_mntners(new_object);
1921 new_auth_vector = get_auth_vector(new_mntners);
1922 if(new_mntners != NULL && new_auth_vector == NULL){
1923 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1924 return UP_AUF; /* auth failed */
1925 }
1926 return authorise(new_auth_vector, credentials, overriden);
1927 }else{
1928 return UP_HOF; /* hierarchical authorisation failed */
1929 }
1930
1931 }
1932 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
1933 old_mntners = get_mntners(old_object);
1934 old_auth_vector = get_auth_vector(old_mntners);
1935 if(old_mntners != NULL && old_auth_vector == NULL){
1936 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1937 return UP_AUF; /* auth failed */
1938 }
1939 if(old_auth_vector){ /* if we have mntners in the old object, use them */
1940 return authorise(old_auth_vector, credentials, overriden);
1941 }else{
1942 new_mntners = get_mntners(new_object);
1943 new_auth_vector = get_auth_vector(new_mntners);
1944 if(new_mntners != NULL && new_auth_vector == NULL){
1945 /* then, the mntners in 'new_mntners' do not exist. Problem. */
1946 return UP_AUF; /* auth failed */
1947 }
1948 return authorise(new_auth_vector, credentials, overriden);
1949 }
1950 }else{ /* both are NULL, mustn't happen */
1951 if(tracing){
1952 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
1953 }
1954 return UP_INT; /* internal error */
1955 }
1956 }
1957
1958
1959 /*
1960 * Handle the "route" type
1961 */
1962 else if(strcmp(type,"route") == 0){
1963 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
1964 old_mntners = get_mntners(old_object);
1965 old_auth_vector = get_auth_vector(old_mntners);
1966 if(old_mntners != NULL && old_auth_vector == NULL){
1967 /* then, the mntners in 'old_mntners' do not exist. Problem. */
1968 return UP_AUF; /* auth failed */
1969 }
1970 return authorise(old_auth_vector, credentials, overriden);
1971 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
1972 /* first we have to find the aut-num object mentioned in the
1973 origin attribute */
1974
1975 aut_num_object = get_aut_num_object(new_object);
1976 if(aut_num_object == NULL){
1977 if(overriden){
1978 return UP_AUTH_OK;
1979 }else{
1980 return UP_HOF; /* hierarchical authorisation failed */
1981 }
1982 }else{/* there is a corresponding aut-num in the db */
1983 if(tracing){
1984 printf("TRACING: check_auth: will try to authorise the route using aut-num\n");
1985 }
1986 aut_num_maintainers = get_mnt_routes(aut_num_object);
1987 if(aut_num_maintainers != NULL){
1988 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1989 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1990 aut_num_auth_OK = true;
1991 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
1992 return UP_HOF;
1993 }
1994 }else{/* aut_num_maintainers is NULL */
1995 aut_num_maintainers = get_mnt_lowers(aut_num_object);
1996 if(aut_num_maintainers != NULL){
1997 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
1998 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
1999 aut_num_auth_OK = TRUE;
2000 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
2001 return UP_HOF; /* hierarchical authorisation failed */
2002 }
2003 }else{/* aut_num_maintainers is NULL */
2004 aut_num_maintainers = get_mntners(aut_num_object);
2005 if(aut_num_maintainers != NULL){
2006 aut_num_auth_vector = get_auth_vector(aut_num_maintainers);
2007 if(authorise(aut_num_auth_vector, credentials, overriden) == UP_AUTH_OK){
2008 aut_num_auth_OK = TRUE;
2009 }else{/* authorise(aut_num_auth_vector, credentials, overriden) != UP_AUTH_OK */
2010 return UP_HOF; /* hierarchical authorisation failed */
2011 }
2012 }else{/* aut_num_maintainers is NULL */
2013 aut_num_auth_OK = TRUE;
2014 }
2015
2016 }
2017 }
2018 if(aut_num_auth_OK){
2019 /* now, we have to find an exact match for this route object.
2020 If there is no exact match object, then we will go on to find
2021 less specific. */
2022 exact_match_routes = get_exact_match_routes(new_object);
2023 if(exact_match_routes != NULL){
2024 exact_match_routes_maintainers = get_mnt_routes_from_list(exact_match_routes);
2025 exact_match_routes_auth_vector = get_auth_vector(exact_match_routes_maintainers);
2026 if(exact_match_routes_maintainers != NULL && exact_match_routes_auth_vector == NULL){
2027 /* then, the mntners in 'exact_match_routes_maintainers' do not exist. Problem. */
2028 return UP_AUF; /* auth failed */
2029 }
2030 if(authorise(exact_match_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
2031 /* then, check mnt_bys of the route itself */
2032 new_mntners = get_mntners(new_object);
2033 new_auth_vector = get_auth_vector(new_mntners);
2034 if(new_mntners != NULL && new_auth_vector == NULL){
2035 /* then, the mntners in 'new_mntners' do not exist. Problem. */
2036 return UP_AUF; /* auth failed */
2037 }
2038 return authorise(new_auth_vector, credentials, overriden);
2039 }else{/*authorise(exact_match_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
2040 return UP_HOF; /* hierarchical authorisation failed */
2041 }
2042 }else{ /* exact_match_routes == NULL */
2043 /* then we have to look for less specific route objs */
2044 less_spec_routes = get_less_spec_routes(new_object);
2045 if(less_spec_routes != NULL){
2046 less_spec_routes_mntners = get_mnt_routes_from_list(less_spec_routes);
2047 less_spec_routes_mntners = g_slist_concat(less_spec_routes_mntners,
2048 get_mnt_lowers_from_list(less_spec_routes));
2049 less_spec_routes_auth_vector = get_auth_vector(less_spec_routes_mntners);
2050 if(less_spec_routes_mntners != NULL && less_spec_routes_auth_vector == NULL){
2051 /* then, the mntners in 'less_spec_routes_mntners' do not exist. Problem. */
2052 return UP_AUF; /* auth failed */
2053 }
2054 if(authorise(less_spec_routes_auth_vector, credentials, overriden) == UP_AUTH_OK){
2055 /* then, check mnt_bys of the route itself */
2056 new_mntners = get_mntners(new_object);
2057 new_auth_vector = get_auth_vector(new_mntners);
2058 if(new_mntners != NULL && new_auth_vector == NULL){
2059 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2060 return UP_AUF; /* auth failed */
2061 }
2062 return authorise(new_auth_vector, credentials, overriden);
2063 }else{/*authorise(less_spec_routes_auth_vector, credentials, overriden) != UP_AUTH_OK*/
2064 return UP_HOF; /* hierarchical authorisation failed */
2065 }
2066 }else{/* less_spec_routes == NULL */
2067 /* so, we have to get the exact match inetnum */
2068 exact_match_inetnum = get_exact_match_inetnum(new_object);
2069 if(exact_match_inetnum != NULL){
2070 exact_match_inetnum_mnt_routes = get_mnt_routes(exact_match_inetnum);
2071 exact_match_inetnum_auth_vector = get_auth_vector(exact_match_inetnum_mnt_routes);
2072 if(exact_match_inetnum_mnt_routes != NULL && exact_match_inetnum_auth_vector == NULL){
2073 /* then, the mntners in 'exact_match_inetnum_mnt_routes' do not exist. Problem. */
2074 return UP_AUF; /* auth failed */
2075 }
2076 if(authorise(exact_match_intenum_auth_vector, credentials, overriden) == UP_AUTH_OK){
2077 /* then, check mnt_bys of the route itself */
2078 new_mntners = get_mntners(new_object);
2079 new_auth_vector = get_auth_vector(new_mntners);
2080 if(new_mntners != NULL && new_auth_vector == NULL){
2081 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2082 return UP_AUF; /* auth failed */
2083 }
2084 return authorise(new_auth_vector, credentials, overriden);
2085 }else{
2086 return UP_HOF; /* hierarchical authorisation failed */
2087 }
2088 }else{/* exact_match_inetnum == NULL */
2089 /* then, we will try to find less spec inetnums */
2090 less_spec_inetnum = get_less_spec_inetnum(new_object);
2091 if(less_spec_inetnum != NULL){
2092 less_spec_inetnum_mntners = get_mnt_routes(less_spec_inetnum);
2093 less_spec_inetnum_mntners = g_slist_concat(less_spec_inetnum_mntners,
2094 get_mnt_lowers(less_spec_inetnum));
2095 less_spec_inetnum_auth_vector = get_auth_vector(less_spec_inetnum_mntners);
2096 if(less_spec_inetnum_mntners != NULL && less_spec_inetnum_auth_vector == NULL){
2097 /* then, the mntners in 'less_spec_inetnum_mntners' do not exist. Problem. */
2098 return UP_AUF; /* auth failed */
2099 }
2100 if(authorise(exact_match_auth_vector, credentials, overriden) == UP_AUTH_OK){
2101 /* then, check mnt_bys of the route itself */
2102 new_mntners = get_mntners(new_object);
2103 new_auth_vector = get_auth_vector(new_mntners);
2104 if(new_mntners != NULL && new_auth_vector == NULL){
2105 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2106 return UP_AUF; /* auth failed */
2107 }
2108 return authorise(new_auth_vector, credentials, overriden);
2109 }else{/* authorise(exact_match_auth_vector, credentials, overriden) != UP_AUTH_OK */
2110 return UP_HOF; /* hierarchical authorisation failed */
2111 }
2112 }else{/* less_spec_inetnum == NULL */
2113 /* now that we couldn't find any route or inetnum object
2114 to be used in authentication. So, only if the auth is
2115 overriden the object will be created. */
2116 if(overriden){
2117 return UP_AUTH_OK;
2118 }else{
2119 return UP_HOF; /* hierarchical authorisation failed */
2120 }
2121 }
2122 }
2123 }
2124 }
2125 }else{/* ! aut_num_auth_OK */
2126 return UP_HOF; /* hierarchical auth failed */
2127 }
2128
2129 }
2130
2131 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2132 old_mntners = get_mntners(old_object);
2133 old_auth_vector = get_auth_vector(old_mntners);
2134 if(old_mntners != NULL && old_auth_vector == NULL){
2135 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2136 return UP_AUF; /* auth failed */
2137 }
2138 if(old_auth_vector){ /* if we have mntners in the old object, use them */
2139 return authorise(old_auth_vector, credentials, overriden);
2140 }else{
2141 new_mntners = get_mntners(new_object);
2142 new_auth_vector = get_auth_vector(new_mntners);
2143 if(new_mntners != NULL && new_auth_vector == NULL){
2144 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2145 return UP_AUF; /* auth failed */
2146 }
2147 return authorise(new_auth_vector, credentials, overriden);
2148 }
2149 }else{ /* both are NULL, mustn't happen */
2150 if(tracing){
2151 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2152 }
2153 return UP_INT; /* internal error */
2154 }
2155 }
2156
2157
2158 /*
2159 * Handle the set objects ("as-set","rtr-set", "peering-set", "route-set" and "filter-set" types
2160 */
2161 else if(strcmp(type,"as-set") == 0 || strcmp(type,"rtr-set") == 0 ||
2162 strcmp(type,"peering-set") == 0 || strcmp(type,"filter-set") == 0 ||
2163 strcmp(type,"route-set") == 0 ){
2164 if( new_object == NULL && old_object != NULL ){ /* the object is to be deleted */
2165 old_mntners = get_mntners(old_object);
2166 old_auth_vector = get_auth_vector(old_mntners);
2167 if(old_mntners != NULL && old_auth_vector == NULL){
2168 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2169 return UP_AUF; /* auth failed */
2170 }
2171 return authorise(old_auth_vector, credentials, overriden);
2172 }else if( new_object != NULL && old_object == NULL ){ /* the object is to be created */
2173 code = set_object->scan_silent(new_object, strlen(new_object));
2174 set_name = get_search_key(set_object, type, new_object);
2175 if(strstr(set_name,":") == NULL ){/* if the name is _not_ hierarchical */
2176 new_mntners = get_mntners(new_object);
2177 new_auth_vector = get_auth_vector(new_mntners);
2178 if(new_mntners != NULL && new_auth_vector == NULL){
2179 /* then, the mntners in 'new_auth_vector' do not exist. Problem. */
2180 return UP_AUF; /* auth failed */
2181 }
2182 return authorise(new_auth_vector, credentials, overriden);
2183 }else{/* the name is hierarchical */
2184 less_specific_object = get_less_specific_set(new_object, type);
2185 if(less_specific_object != NULL){/* such an object exists */
2186 temp_obj = new Object();
2187 code = temp_obj->scan_silent(less_specific_object, strlen(less_specific_object));
2188 less_specific_object_type = get_class_type(temp_obj);
2189 delete(temp_obj);
2190 if(strcmp(less_specific_object_type, "aut-num") == 0){/* if this is an aut-num object */
2191 less_specific_mnt_lowers = get_mnt_lowers(less_specific_object);
2192 less_specific_auth_vector = get_auth_vector(less_specific_mnt_lowers);
2193 if(less_specific_mnt_lowers != NULL && less_specific_auth_vector == NULL){
2194 /* then, the mntners in 'less_specific_auth_vector' do not exist. Problem. */
2195 return UP_AUF; /* auth failed */
2196 }
2197 if(less_specific_auth_vector != NULL){
2198 return authorise(less_specific_auth_vector, credentials, overriden);
2199 }else{/* the less specific object doesn't contain any mnt-lower */
2200 less_specific_mntners = get_mntners(less_specific_object);
2201 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2202 if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2203 /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2204 return UP_AUF; /* auth failed */
2205 }
2206 if(less_specific_auth_vector != NULL){/* less spec object has some mnt-by attribs,
2207 use them */
2208 return authorise(less_specific_auth_vector, credentials, overriden);
2209 }else{/* the less specific object doesn't contain any mnt-by either */
2210 if(overriden){
2211 return UP_AUTH_OK;
2212 }else{
2213 return UP_HOF; /* hierarchical authorisation failed */
2214 }
2215 }
2216 }
2217 }else{ /* this is _not_ an aut-num object*/
2218 less_specific_mntners = get_mntners(less_specific_object);
2219 less_specific_auth_vector = get_auth_vector(less_specific_mntners);
2220 if(less_specific_mntners != NULL && less_specific_auth_vector == NULL){
2221 /* then, the mntners in 'less_specific_mntners' do not exist. Problem. */
2222 return UP_AUF; /* auth failed */
2223 }
2224 if(less_specific_auth_vector != NULL ){/* the set obj has some mnt-by attribs */
2225 return authorise(less_specific_auth_vector, credentials, overriden);
2226 }else{
2227 if(overriden){
2228 return UP_AUTH_OK;
2229 }else{
2230 return UP_HOF; /* hierarchical authorisation failed */
2231 }
2232 }
2233 }
2234
2235 }else{/* we don't have a less specific of this set object in the DB */
2236 return UP_HOF; /* hierarchical authorisation failed */
2237 }
2238 }
2239 }else if( new_object != NULL && old_object != NULL ){ /* this is an update */
2240 old_mntners = get_mntners(old_object);
2241 old_auth_vector = get_auth_vector(old_mntners);
2242 if(old_mntners != NULL && old_auth_vector == NULL){
2243 /* then, the mntners in 'old_auth_vector' do not exist. Problem. */
2244 return UP_AUF; /* auth failed */
2245 }
2246 if(old_auth_vector){ /* if we have mntners in the old object, use them */
2247 return authorise(old_auth_vector, credentials, overriden);
2248 }else{
2249 new_mntners = get_mntners(new_object);
2250 new_auth_vector = get_auth_vector(new_mntners);
2251 if(new_mntners != NULL && new_auth_vector == NULL){
2252 /* then, the mntners in 'new_mntners' do not exist. Problem. */
2253 return UP_AUF; /* auth failed */
2254 }
2255 return authorise(new_auth_vector, credentials, overriden);
2256 }
2257 }else{ /* both are NULL, mustn't happen */
2258 if(tracing){
2259 cout << "TRACING: check_auth: internal error: Both pointers are NULL" << endl;
2260 }
2261 return UP_INT; /* internal error */
2262 }
2263
2264
2265
2266
2267
2268 }else{ /* We exhausted all object classes. If we are here, then there is a problem */
2269 cout << "check_auth: This type '" << type << "' is unknown" << endl;
2270 return UP_NIY; /* not implemented yet */
2271 }
2272 return UP_AUF; /* if we come to this point, then auth failed */
2273 }
2274
2275
2276
2277
2278
2279
2280 /* Gets the old version of the given "arg" object, which is in char * format
2281 and returns the old version again in char * format */
2282
2283 char * get_old_version(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2284
2285 bool code = true;
2286 char *type=NULL, *primary_search_key = NULL, *search_string = NULL;
2287 Object *o;
2288 o = new Object;
2289 char *result = NULL, *origin = NULL;
2290
2291 error = 0;
2292 code = o->scan_silent(arg,strlen(arg));
2293 type = get_class_type(o);
2294 primary_search_key = get_search_key(o, type, arg);
2295 if(tracing) {
2296 cout << "type=" << type << endl;
2297 cout << "primary_search_key=" << primary_search_key << endl;
2298 }
2299 /* if the object is a pn ro a ro object, then get all pn/ro's with the
2300 same NIC hdl */
2301 if(strcmp(type,"person") == 0 || strcmp(type,"role") == 0){
2302 /* prepare the search string */
2303 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2304 + strlen("person,role") + 2);
2305 sprintf(search_string, "-x -R -r -Tperson,role %s", primary_search_key);
2306 }else{
2307 /* prepare the search string */
2308 search_string = (char *)malloc(strlen(primary_search_key) + strlen("-x -R -r -T")
2309 + strlen(type) + 2);
2310 sprintf(search_string, "-x -R -r -T%s %s",type, primary_search_key);
2311 }
2312 result = send_and_get(query_host, query_port, search_string);
2313 if(tracing) {
2314 cout << "TRACING: send_and_get has returned" << endl;
2315 cout << "TRACING: send_and_get returned (with search '"<< search_string <<"'): " << endl
2316 << result << endl;
2317 }
2318 /* Attention: here we must also check these:
2319 for ro/pn objects: The name must also the same. When the NIC hdl is the
2320 same but names are different, we must somehow return an error.
2321 Also, when we search for a person, we must also look for role objects
2322 (and vice versa) since the RIPupdate does not distinguish between
2323 role & person objects. We have to check it here.
2324 for rt objects: We also have to check the identicalness of origin
2325 attributes.
2326
2327 These are not yet implemented.
2328 */
2329
2330 if(strcmp(type,"route") == 0){
2331 if(tracing) {
2332 printf("TRACING: This is a route\n");
2333 }
2334 /* if this is a route, then we must filter out the routes with different
2335 origin attributes */
2336 origin = get_search_key(o, "origin", arg);
2337 if(tracing) {
2338 printf("TRACING: Got origin of route: %s\n", origin);
2339 }
2340 result = filter_out_diff_origins(result, origin);
2341 if(tracing) {
2342 printf("TRACING: Filtered routes\n");
2343 }
2344 }
2345 // count the objects
2346 if(count_objects(result) == 0){
2347 result = NULL; /* we don't have such an object */
2348 }else if(count_objects(result) == 1){
2349 result = take_object(result);
2350 if(tracing) {
2351 cout << "TRACING: Take_object returned ***\n" << result << "***" << endl;
2352 }
2353 }else{ /* we have more than one objects, error! */
2354 error = UP_MOR;
2355 return NULL;
2356 }
2357 return result;
2358 }
2359
2360
2361
2362
2363 /* Gets a credentials_struct whose 'from' field will be filled in and
2364 the mail header. Finds the 'From:' line in the header and sets
2365 the 'from' field to this line (all line, including the 'From:' string,
2366 since some users have put regexps which match the whole line in their
2367 'auth' attributes.) */
2368 void process_mail_header(credentials_struct * credentials_ptr, char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2369 char * header = strdup(arg);
2370 char * temp = (char *)malloc(strlen(header));
2371 while(index(header, '\n') != NULL){
2372 temp = strdup(header);
2373 temp[index(temp, '\n') - temp] = '\0';
2374 if(strstr(temp, "From:") == temp){
2375 if(tracing) {
2376 printf("TRACING: process_mail_header: Assigning %s\n", temp);
2377 }
2378 credentials_ptr->from = strdup(temp);
2379 free(temp);
2380 return;
2381 }
2382 header = header + (index(header, '\n') - header + 1);
2383 }
2384 free(temp);
2385 }
2386
2387
2388
2389
2390
2391
2392 void up_string_pack(char *dest, const char *source){
/* [<][>][^][v][top][bottom][index][help] */
2393
2394 if(tracing) {
2395 printf("TRACING: up_string_pack running\n");
2396 }
2397
2398
2399
2400 /*----------------------------------------------------------------------*\
2401
2402 * Function to rewrite a line of text with only one blankspace between *
2403 * each word.
2404 *
2405
2406 \*----------------------------------------------------------------------*/
2407
2408
2409 /*
2410 * This while loop continues until the NULL character is copied into
2411 * the destination string. If a tab character is copied into the
2412 * destination string, it is replaced with a blank-space character.
2413 *
2414 * Multiple blank-space and/or tab characters are skipped in the source
2415 * string until any other character is found.
2416 */
2417
2418 while (1)
2419 {
2420 *dest = *source;
2421
2422 if (*dest == '\t')
2423 (*dest = ' ');
2424
2425 /* Exit if have copied the end of the string. */
2426 if (*dest == '\0')
2427 return;
2428
2429 /*
2430 * If the source character was a blank-space or a tab, move to the next
2431 * source character. While the source character is a blank-space or a
2432 * tab, move to the next character (i.e. ignore these characters). When
2433 * any other character is found in the source string, move to the next
2434 * element of the destination string.
2435 *
2436 * Otherwise, simultaneously, move to the next elements of the destination
2437 * and the source strings.
2438 */
2439
2440
2441
2442 if ( (*source == ' ') || (*source == '\t') )
2443 {
2444 ++source;
2445 while ( (*source == ' ') || (*source == '\t') )
2446 {
2447 ++source;
2448 }
2449
2450 ++dest;
2451 }
2452 else
2453 {
2454 ++dest;
2455 ++source;
2456 }
2457 }
2458 }
2459
2460
2461
2462
2463
2464
2465
2466
2467 /* strips lines beginning with "delete:" off */
2468 char * delete_delete_attrib(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2469
2470 char ** temp = NULL;
2471 char * string = NULL;
2472 int i;
2473
2474 if(arg == NULL){
2475 return NULL;
2476 }
2477
2478 /* split the string into lines */
2479 temp = g_strsplit (arg, "\n", 0);
2480
2481 for(i=0; temp[i] != NULL; i++){
2482 /* if the line begins with "delete:", then do not copy it */
2483 if(strstr(temp[i], "delete:") != temp[i]){
2484 if(string == NULL){
2485 string = strdup(temp[i]);
2486 }else{
2487 string = (char *)realloc(string, strlen(string) + strlen(temp[i]) + 2);
2488 string = strcat(string, "\n");
2489 string = strcat(string, temp[i]);
2490 }
2491 }
2492 }
2493 g_strfreev(temp);
2494 return string;
2495 }
2496
2497
2498
2499
2500
2501
2502 /* replaces the erase_str occurences with insert_str in str (which is a ptr to GString) */
2503 char * UP_replace_strings(char * str, const char * erase_str, const char * insert_str){
/* [<][>][^][v][top][bottom][index][help] */
2504
2505 GString * g_str;
2506 int pos;
2507 char * result_str;
2508
2509 /* erase_str mustn't be NULL */
2510 assert(erase_str != NULL);
2511
2512 /* if insert str is NULL, make it empty string */
2513 if(insert_str == NULL){
2514 insert_str = strdup("");
2515 }
2516
2517 g_str = g_string_new(str);
2518
2519 /* replace erase_str with insert_str */
2520 while(strstr(g_str->str, erase_str) != NULL){
2521 pos = strstr(g_str->str, erase_str) - g_str->str;
2522 g_str = g_string_erase(g_str, pos, strlen(erase_str));
2523 if(insert_str != NULL){
2524 g_str = g_string_insert(g_str, pos, insert_str);
2525 }
2526 }
2527
2528
2529 /* save the result string */
2530 result_str = strdup(g_str->str);
2531
2532 /* free the GString structure (TRUE means 'also free the char string') */
2533 g_string_free(g_str, TRUE);
2534
2535 return result_str;
2536
2537 }
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548 /* replaces the erase_str occurences with insert_str in g_str (which is a ptr to GString) */
2549 GString * UP_replace_GStrings(GString * g_str, const char * erase_str, const char * insert_str){
/* [<][>][^][v][top][bottom][index][help] */
2550
2551 int pos;
2552
2553 if(insert_str == NULL){/* then don't do anything */
2554 return g_str;
2555 }
2556
2557 /* replace erase_str with insert_str */
2558 while(strstr(g_str->str, erase_str) != NULL){
2559 pos = strstr(g_str->str, erase_str) - g_str->str;
2560 g_str = g_string_erase(g_str, pos, strlen(erase_str));
2561 if(insert_str != NULL){
2562 g_str = g_string_insert(g_str, pos, insert_str);
2563 }
2564 }
2565 return g_str;
2566
2567 }
2568
2569
2570
2571
2572
2573
2574
2575
2576 /* looks if two objects are identical or not.
2577 Takes two objects as char *, and returns 1 if
2578 they are identical, returns 0 if not.
2579
2580 Algorithm is very simple: All strings of tabs and
2581 white spaces are collapsed into a single white space,
2582 and then the strings are compared (strcmp) */
2583 int identical(const char * old_version, const char * new_version){
/* [<][>][^][v][top][bottom][index][help] */
2584 char * arg1 = strdup(old_version);
2585 char * arg2 = strdup(new_version);
2586 int result = 0;
2587 char *temp1, *temp2;
2588 char *temp;
2589
2590
2591 arg1 = g_strstrip(arg1);
2592 arg2 = g_strstrip(arg2);
2593
2594 /* delete the 'delete:' attrib */
2595 arg2 = delete_delete_attrib(arg2);
2596 /* convert tabs to white spaces */
2597 arg1 = g_strdelimit(arg1, "\t", ' ');
2598 arg2 = g_strdelimit(arg2, "\t", ' ');
2599
2600 temp1 = (char *)malloc(strlen(arg1) + 1);
2601 temp2 = (char *)malloc(strlen(arg2) + 1);
2602 up_string_pack(temp1, arg1);
2603 up_string_pack(temp2, arg2);
2604
2605 /* if there are still \r's at the end of strings, remove them */
2606 if((temp1[strlen(temp1) - 1]) == '\r'){
2607 temp1[strlen(temp1) - 1] = '\0';
2608 }
2609 if((temp2[strlen(temp2) - 1]) == '\r'){
2610 temp2[strlen(temp2) - 1] = '\0';
2611 }
2612
2613 /* there may be white spaces at the end of the strings now, remove them */
2614 if((temp1[strlen(temp1) - 1]) == ' '){
2615 temp1[strlen(temp1) - 1] = '\0';
2616 }
2617 if((temp2[strlen(temp2) - 1]) == ' '){
2618 temp2[strlen(temp2) - 1] = '\0';
2619 }
2620
2621 /* remove the white spaces just before the EOLs (since this is not taken care of by
2622 the up_string_pack func) */
2623 temp = UP_replace_strings(temp1, " \n", "\n");
2624 free(temp1);
2625 temp1 = temp;
2626
2627 temp = UP_replace_strings(temp2, " \n", "\n");
2628 free(temp2);
2629 temp2 = temp;
2630
2631
2632
2633 result = strcmp(temp1, temp2);
2634 if(tracing){
2635 printf("TRACING: identical: the objects are:\n[%s]\n[%s]\n", temp1, temp2);
2636 printf("TRACING: identical: the lengths are:\n[%i]\n[%i]\n", strlen(temp1), strlen(temp2));
2637 }
2638 free(arg1);
2639 free(arg2);
2640 free(temp1);
2641 free(temp2);
2642 if(result == 0){
2643 if(tracing) {
2644 printf("TRACING: identical returning 1\n");
2645 }
2646 return 1;
2647 }else{
2648 if(tracing) {
2649 printf("TRACING: identical returning 0\n");
2650 }
2651 return 0;
2652 }
2653 }
2654
2655
2656
2657
2658
2659
2660 /* constructs an initials string from a given name (for NIC hdl generation) */
2661 char * find_initials(const char * arg){
/* [<][>][^][v][top][bottom][index][help] */
2662
2663 char * temp, * temp2;
2664 char * initials = NULL;
2665 int len, i;
2666 char ** vector;
2667
2668 temp = strdup(arg);
2669 g_strstrip(temp);
2670 temp2 = (char *)malloc(strlen(temp) + 1);
2671 up_string_pack(temp2, temp);
2672 vector = g_strsplit(temp2, " ", 0);
2673 for(i = 0; vector[i] != NULL && i < 4; i++){
2674 if(strlen(vector[i]) > 0){
2675 if(initials == NULL){
2676 initials = (char *)malloc(2);
2677 initials[0] = vector[i][0]; initials[1] = '\0';
2678 }else{
2679 len = strlen(initials);
2680 initials = (char *)realloc(initials, len + 2 );
2681 initials[len] = vector[i][0];
2682 initials[len + 1] = '\0';
2683 }
2684 }
2685 }
2686 free(temp);free(temp2);g_strfreev(vector);
2687 return initials;
2688 }
2689
2690
2691
2692
2693
2694 /* Gets the letter combination to be used in the automatically
2695 generated NIc handle. It the letter combination is specified
2696 in the AUTO NIC handle, return that. If not, return NULL
2697 (in which case the initials of the name must be used) */
2698 char * get_combination_from_autonic(const char * autonic){
/* [<][>][^][v][top][bottom][index][help] */
2699
2700 GString * temp;
2701 char * str = NULL;
2702
2703 temp = g_string_new(autonic);
2704 temp = g_string_up(temp);
2705 temp = g_string_erase(temp, 0, strlen("AUTO-"));
2706 /* delete all digits from the beginning of the string */
2707 while(temp->len > 0 && ((temp->str)[0] >= '0' && (temp->str)[0] <= '9')){
2708 temp = g_string_erase(temp, 0, 1);
2709 }
2710 if(temp->len == 0){
2711 g_string_free(temp, TRUE);
2712 return NULL;
2713 }else{
2714 str = temp->str;
2715 g_string_free(temp, FALSE);
2716 return str;
2717 }
2718
2719 }
2720
2721
2722
2723
2724
2725
2726 /* Gets an object whose NIC hdl is AUTO and to be modified (to be sent to RIPupdate)
2727 and modifies the nic-hdl: attribute, returns the new object.
2728 For example, "nic-hdl: AUTO-1" becomes "nic-hdl: HG*-RIPE . Also,
2729 auto_nic is set to "AUTO-1"
2730 auto_nic must be allocated enough memory before replace_AUTO_NIC_hdl called */
2731 char * replace_AUTO_NIC_hdl(char * arg, char * auto_nic_hdl){
/* [<][>][^][v][top][bottom][index][help] */
2732
2733 GString* temp_string;
2734 char * to_be_returned = NULL;
2735 char * person_role_name= NULL;
2736 char * initials = NULL;
2737 char ** temp = NULL;
2738 int i, pos;
2739 Object * o = new Object;
2740
2741 temp = g_strsplit(arg, "\n", 0);
2742
2743 for(i = 0; temp[i] != NULL; i++){
2744 if(strstr(temp[i], "nic-hdl:") == temp[i]){/* if it starts with nic-hdl */
2745 temp_string = g_string_new(temp[i]);
2746 temp_string = g_string_down(temp_string);
2747 if(strstr(temp_string->str, "auto-") != NULL){
2748 auto_nic_hdl = strncpy(auto_nic_hdl, strstr(temp_string->str, "auto-"),
2749 temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2750 auto_nic_hdl[temp_string->len + temp_string->str - strstr(temp_string->str, "auto-")] = '\0';
2751 g_strstrip(auto_nic_hdl);
2752 if(tracing){
2753 printf("TRACING: auto_nic is [%s]\n", auto_nic_hdl);
2754 }
2755 pos = strstr(temp_string->str, "auto-") - temp_string->str;
2756 temp_string = g_string_erase(temp_string,
2757 strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic_hdl)/*strlen("AUTO-")*/);
2758 /* as the suffix to the AUTO nic handle we use the first updatable
2759 source. Since currently we don't support multiple sources,
2760 this is not a problem but when we support it, we must change this */
2761 temp_string = g_string_insert(temp_string, pos, sources[0]);
2762 temp_string = g_string_insert(temp_string, pos, "*-");
2763 o->scan_silent(arg, strlen(arg));
2764 person_role_name = get_attribute(o, get_class_type(o), arg);
2765 delete(o);
2766 /* if the letter combination is already specified, get it */
2767 initials = get_combination_from_autonic(auto_nic_hdl);
2768 /* if the letter combination is not in the AUTO nichdl, obtain it from the name */
2769 if(initials == NULL){
2770 initials = find_initials(person_role_name);
2771 }
2772 free(person_role_name);
2773 temp_string = g_string_insert(temp_string, pos, initials);
2774 free(initials);
2775
2776 if(to_be_returned == NULL){
2777 to_be_returned = strdup(temp_string->str);
2778 g_string_free(temp_string, TRUE);
2779 }else{
2780 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2781 to_be_returned = strcat(to_be_returned, "\n");
2782 to_be_returned = strcat(to_be_returned, temp_string->str);
2783 g_string_free(temp_string, TRUE);
2784 }
2785 }else{
2786 if(to_be_returned == NULL){
2787 to_be_returned = strdup(temp[i]);
2788 }else{
2789 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2790 to_be_returned = strcat(to_be_returned, "\n");
2791 to_be_returned = strcat(to_be_returned, temp[i]);
2792 }
2793 }
2794 }else{/* if it doesn't begin with nic-hdl */
2795 if(to_be_returned == NULL){
2796 to_be_returned = strdup(temp[i]);
2797 }else{
2798 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2799 strcat(to_be_returned, "\n");
2800 strcat(to_be_returned, temp[i]);
2801 }
2802
2803 }
2804
2805 }
2806 g_strfreev (temp);
2807 return to_be_returned;
2808 }
2809
2810
2811
2812
2813
2814
2815
2816 /* replaces the refs to AUTO NIC hdls with the assigned one */
2817
2818 char * replace_refs_to_AUTO_NIC_hdl(char * changed_obj, char * arg, GHashTable * auto_nic_hash){
/* [<][>][^][v][top][bottom][index][help] */
2819
2820 char * auto_nic = NULL;
2821 GString* temp_string;
2822 char * to_be_returned = NULL, * tempstr = NULL;
2823 char ** temp = NULL;
2824 int i, pos;
2825
2826 if(tracing){
2827 printf("TRACING: replace_refs_to_AUTO_NIC_hdl is running: changed_obj:[%s], arg:[%s]\n",
2828 changed_obj ? changed_obj : "NULL", arg ? arg : "NULL");
2829 }
2830
2831
2832 temp = g_strsplit(arg, "\n", 0);
2833
2834 for(i = 0; temp[i] != NULL; i++){
2835 if( strstr(temp[i], "admin-c:") == temp[i] /* if it starts with admin-c */
2836 || strstr(temp[i], "tech-c:" ) == temp[i] /* or if it starts with tech-c */
2837 || strstr(temp[i], "zone-c:" ) == temp[i] /* or if it starts with zone-c */
2838 || strstr(temp[i], "author:" ) == temp[i]){ /* or if it starts with author */
2839 temp_string = g_string_new(temp[i]);
2840 temp_string = g_string_down(temp_string);
2841 if(strstr(temp_string->str, "auto-") != NULL){
2842 auto_nic = (char *)malloc(temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") + 1);
2843 auto_nic = strncpy(auto_nic, strstr(temp_string->str, "auto-"),
2844 temp_string->len + temp_string->str - strstr(temp_string->str, "auto-") );
2845 auto_nic[temp_string->str + temp_string->len - strstr(temp_string->str, "auto-")] = '\0';
2846 g_strstrip(auto_nic);
2847 if(tracing){
2848 printf("TRACING: replace_refs_to_AUTO_NIC_hdl: auto_nic is [%s]\n", auto_nic);
2849 }
2850 pos = strstr(temp_string->str, "auto-") - temp_string->str;
2851 temp_string = g_string_erase(temp_string,
2852 strstr(temp_string->str, "auto-") - temp_string->str, strlen(auto_nic)/*strlen("AUTO-")*/);
2853
2854 /* if we have this AUTO NIC hdl in the hash, put it. */
2855 if(g_hash_table_lookup(auto_nic_hash, auto_nic)){
2856 temp_string = g_string_insert(temp_string, pos, (char *)g_hash_table_lookup(auto_nic_hash, auto_nic));
2857 }else{/* else, return 0 immediately */
2858 g_strfreev (temp);
2859 return NULL;
2860 }
2861
2862 if(to_be_returned == NULL){
2863 to_be_returned = strdup(temp_string->str);
2864 g_string_free(temp_string, TRUE);
2865 }else{
2866 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + temp_string->len + 2);
2867 to_be_returned = strcat(to_be_returned, "\n");
2868 to_be_returned = strcat(to_be_returned, temp_string->str);
2869 g_string_free(temp_string, TRUE);
2870 }
2871 }else{
2872 if(to_be_returned == NULL){
2873 to_be_returned = strdup(temp[i]);
2874 }else{
2875 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2876 to_be_returned = strcat(to_be_returned, "\n");
2877 to_be_returned = strcat(to_be_returned, temp[i]);
2878 }
2879 }
2880 }else{/* if it doesn't begin with ac,tc,ac or author */
2881 if(to_be_returned == NULL){
2882 to_be_returned = strdup(temp[i]);
2883 }else{
2884 to_be_returned = (char *)realloc(to_be_returned, strlen(to_be_returned) + strlen(temp[i]) + 2);
2885 strcat(to_be_returned, "\n");
2886 strcat(to_be_returned, temp[i]);
2887 }
2888
2889 }
2890
2891 }
2892 g_strfreev (temp);
2893
2894 /* now, if we don't have a '\n' at the end of the to_be_returned string, we will
2895 add one, since RAToolSet parser cannot deal with objects without a '\n' at the end */
2896 if(to_be_returned[strlen(to_be_returned) - 1] != '\n'){
2897 /* so, add a '\n' */
2898 tempstr = (char *)malloc(strlen(to_be_returned) + 2);
2899 sprintf(tempstr, "%s\n", to_be_returned);
2900 free(to_be_returned);
2901 to_be_returned = tempstr;
2902 }
2903
2904 if(tracing){
2905 printf("TRACING: replace_refs_to_AUTO_NIC_hdl is returning,\nto_be_returned=[%s]\n", to_be_returned);
2906 }
2907 return to_be_returned;
2908 }
2909
2910
2911
2912
2913
2914
2915
2916
2917 /* Takes an object in a char * , and returns 1 if this object has
2918 an AUTO NIC handle. Otherwise, returns 0 */
2919 int has_AUTO_NIC_hdl(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
2920
2921 Object * o = new Object();
2922 GSList * attributes = NULL;
2923 bool code;
2924
2925 code = o->scan_silent(object, strlen(object));
2926
2927 if(code && !(o->isDeleted)){
2928 attributes = get_attributes(o, "nic-hdl", object);
2929 if(attributes != NULL){
2930 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2931 g_slist_free(attributes);
2932 delete(o);
2933 return 1;
2934 }
2935 }
2936 /* if control reaches here, then we will return 0 */
2937 g_slist_free(attributes);
2938 delete(o);
2939 return 0;
2940 }else{/* it doesn't pass syntax check. So, it doesn't matter if
2941 it contains refs to AUTO NIC hdls. */
2942 delete(o);
2943 return 0;
2944 }
2945
2946 }
2947
2948
2949 /* Takes an object in a char * , and returns 1 if this object contains
2950 a reference to an AUTO NIC handle. Otherwise, returns 0 */
2951 int has_ref_to_AUTO_nic_hdl(const char * object){
/* [<][>][^][v][top][bottom][index][help] */
2952
2953 Object * o = new Object();
2954 GSList * attributes = NULL;
2955 bool code;
2956
2957 code = o->scan_silent(object, strlen(object));
2958
2959 if(code && !(o->isDeleted)){
2960 attributes = get_attributes(o, "admin-c", object);
2961 if(attributes != NULL){
2962 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2963 g_slist_free(attributes);
2964 delete(o);
2965 return 1;
2966 }
2967 }
2968 g_slist_free(attributes);
2969 attributes = get_attributes(o, "tech-c", object);
2970 if(attributes != NULL){
2971 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2972 g_slist_free(attributes);
2973 delete(o);
2974 return 1;
2975 }
2976 }
2977
2978 g_slist_free(attributes);
2979 attributes = get_attributes(o, "zone-c", object);
2980 if(attributes != NULL){
2981 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2982 g_slist_free(attributes);
2983 delete(o);
2984 return 1;
2985 }
2986 }
2987 g_slist_free(attributes);
2988 attributes = get_attributes(o, "author", object);
2989 if(attributes != NULL){
2990 if(strstr_in_list(attributes, "AUTO-") == 1){/* if it contains a ref to AUTO nic */
2991 g_slist_free(attributes);
2992 delete(o);
2993 return 1;
2994 }
2995 }
2996 /* if control reaches here, then we will return 0 */
2997 delete(o);
2998 return 0;
2999 }else{/* it doesn't pass syntax check. So, it doesn't matter if
3000 it contains refs to AUTO NIC hdls. */
3001 delete(o);
3002 return 0;
3003 }
3004
3005 }
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015 /* Gets the "From" line of the incoming mail message and finds out an
3016 address to send the acknowledgement */
3017 char * find_email_address(const char * from_line){
/* [<][>][^][v][top][bottom][index][help] */
3018 char * pos1 = NULL, * pos2 = NULL;
3019 char * temp = NULL;
3020
3021 if(from_line == NULL){
3022 return NULL;
3023 }
3024 if(strstr(from_line, "From:") != from_line){
3025 temp = strdup(from_line);
3026 }else{
3027 temp = strdup(from_line + strlen("From:"));
3028 }
3029 g_strstrip(temp);
3030 if(index(temp, '<')){/* then the line is something like '"John White" <john@inter.net>' */
3031 pos1 = index(temp, '<');
3032 pos2 = index(temp, '>');
3033 temp = strncpy(temp, pos1 + 1, pos2 - pos1 -1);
3034 temp[pos2 - pos1 - 1] = '\0';
3035 if(tracing) {
3036 printf("TRACING: find_email_address temp=[%s]\n", temp);
3037 }
3038
3039 return temp;
3040 }else{/* the line contains only the address, then */
3041 return temp;
3042 }
3043 }
3044
3045
3046 /* removes the '\n's and '\r's at the end of the arg, and returns it */
3047 char * UP_remove_EOLs(char * arg){
/* [<][>][^][v][top][bottom][index][help] */
3048
3049 while(strlen(arg) > 0 &&
3050 (arg[strlen(arg) - 1] == '\n' ||
3051 arg[strlen(arg) - 1] == '\r')){
3052 arg[strlen(arg) - 1] = '\0';
3053 }
3054
3055 return arg;
3056 }
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067 /* Duplicates the given arg, and replaces
3068 $FROM,
3069 $SUBJECT,
3070 $MDATE,
3071 $MSGID,
3072 $CC,
3073 $HUMAILBOX
3074 $AUTOBOX
3075
3076 and $TIME & $DATE
3077
3078 strings with the corresponding variables.
3079
3080 */
3081 char * UP_replace_globals(const char * arg){
/* [<][>][^][v][top][bottom][index][help] */
3082
3083 GString * g_str;
3084 int pos;
3085 char * to_be_returned;
3086 time_t cur_time;
3087 char * temp, * time_str, * date_str;
3088
3089
3090 /* get time */
3091 cur_time = time(NULL);
3092 temp = strdup(ctime(&cur_time));
3093 /* temp is now something like "Fri Sep 13 00:00:00 1986\n\0", fields are const width */
3094
3095 time_str = (char *)malloc(9);
3096 time_str = strncpy(time_str, temp + 11, 8);
3097 time_str[8] = '\0';
3098
3099 date_str = (char *)malloc(16);
3100 date_str = strncpy(date_str, temp, 11);
3101 date_str[11] = '\0';
3102 date_str = strncat(date_str, temp + 20, 4);
3103
3104
3105 free(temp);
3106
3107 g_str = g_string_new(arg);
3108
3109 g_str = UP_replace_GStrings(g_str, "$TIME", time_str);
3110
3111 g_str = UP_replace_GStrings(g_str, "$DATE", date_str);
3112
3113 g_str = UP_replace_GStrings(g_str, "$SUBJECT", update_mail_subject);
3114
3115 g_str = UP_replace_GStrings(g_str, "$FROM", update_mail_sender);
3116
3117 g_str = UP_replace_GStrings(g_str, "$MDATE", update_mail_date);
3118
3119 g_str = UP_replace_GStrings(g_str, "$MSGID", update_mail_ID);
3120
3121 g_str = UP_replace_GStrings(g_str, "$CC", update_mail_cc);
3122 if(update_mail_cc == NULL){
3123 g_str = UP_replace_GStrings(g_str, "$CC", "");
3124 }
3125 g_str = UP_replace_GStrings(g_str, "$HUMAILBOX", humailbox);
3126
3127 g_str = UP_replace_GStrings(g_str, "$AUTOBOX", autobox);
3128
3129 free(time_str);
3130 free(date_str);
3131
3132 to_be_returned = strdup(g_str->str);
3133 g_string_free(g_str, 1);
3134 return to_be_returned;
3135 }
3136
3137 /* Get the type of the object, which is represented as a char * */
3138 char * get_class_type_char(char * object){
/* [<][>][^][v][top][bottom][index][help] */
3139 bool code;
3140 Object * o;
3141 char * type;
3142 char * temp;
3143
3144 /* if there is no '\n' at the end of char * already, o->scan chokes. So, add it.
3145 (no harm in having more than one) */
3146 temp = (char *)malloc(strlen(object) + 2);
3147 sprintf(temp, "%s\n", object);
3148
3149 if(tracing) {
3150 printf("TRACING: get_class_type_char is running, object is \n[%s]\n", object);
3151 }
3152 o = new Object;
3153 code = o->scan_silent(temp,strlen(temp));
3154
3155 type = get_class_type(o);
3156
3157 free(temp);
3158 delete(o);
3159 return type;
3160
3161 }