modules/up/UP_extrnl_syntax.c
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following functions.
- up_check_source_attr
- up_check_country_attr
- up_check_nicsuffixes
- up_get_dates
- up_changed_has_date
- UP_get_current_date
- up_add_dates
- up_check_date_order
- up_check_date
- up_check_dates_syntax
- up_check_changed_attr
- up_check_an_inetnum_attr
- up_add_keycert_attrs
- up_reconstruct_object
- UP_check_external_syntax
- UP_generate_kc_attrs
- up_assign_i6_status
- up_add_inet6num_attrs
1 /***************************************
2 $Revision: 1.16 $
3
4 UP external syntax checks
5
6 Status: REVIEWED, NOT TESTED
7
8 Author(s): Engin Gunduz
9
10 ******************/ /******************
11 Modification History:
12 engin (15/12/2000) Created.
13 denis (31/08/2001) Modified for new API
14 ******************/ /******************
15 Copyright (c) 2001,2002 RIPE NCC
16
17 All Rights Reserved
18
19 Permission to use, copy, modify, and distribute this software and its
20 documentation for any purpose and without fee is hereby granted,
21 provided that the above copyright notice appear in all copies and that
22 both that copyright notice and this permission notice appear in
23 supporting documentation, and that the name of the author not be
24 used in advertising or publicity pertaining to distribution of the
25 software without specific, written prior permission.
26
27 THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
28 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
29 AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
30 DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
31 AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
32 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
33 ***************************************/
34
35
36 /*#include "rpsl/object.hh"*/
37 #include "UP_extrnl_syntax.h"
38 #include "dbupdate.h"
39
40 #define UP_DATE_OK 0
41 #define UP_DATE_SYNERR 1
42 #define UP_DATE_FUTURE 2
43 #define UP_DATE_TOOSMALL 3
44 #define UP_DATE_INVMONTH 4
45 #define UP_DATE_INVDAY 5
46 #define UP_DATE_WRONGFORMAT 6
47 #define UP_DATE_NOK 7
48
49 char * up_date_errmsgs[]=
50 {
51
52 "OK",
53 "Syntax error in date of 'changed' attribute",
54 "Date in the future in 'changed' attribute",
55 "Date is older than the database itself in 'changed' attribute",
56 "Invalid month in date in 'changed' attribute",
57 "Invalid day in date in 'changed' attribute",
58 "Date must be in YYYYMMDD format in 'change' attribute",
59 "Syntax error in date of 'changed' attribute"
60 };
61
62
63 extern int tracing;
64
65 extern char * fingerprint;
66 extern char * keyowner;
67
68 extern int num_sources;
69 extern char *countries[];
70 extern char *nicsuffixes[];
71 extern ca_updDbSource_t **upd_source_hdl;
72
73
74 /* void up_check_source_attr
75 checks for a valid source in the 'source' attributes */
76 void up_check_source_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
77 {
78 int valid,i ;
79 char *source_name;
80 char *temp;
81 GList *source_list;
82
83 if (tracing)
84 {
85 printf("TRACING: up_check_source_attr running\n");
86 }
87
88 source_list = rpsl_object_get_attr(external_syntax_obj, "source");
89
90 valid = i = 0 ;
91 if ( source_list )
92 {
93 source_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(source_list->data) );
94 for ( i=0; i<num_sources; i++ )
95 {
96 if ( ! strcasecmp( source_name, upd_source_hdl[i]->name) )
97 {
98 valid = 1;
99 break;
100 }
101 }
102
103 /* while(sources[i])
104 {
105 if(strcasecmp(sources[i++],source_name) == 0)
106 {
107 valid = 1;
108 break;
109 }
110 } */
111
112 g_list_free(source_list);
113 }
114
115 if (!valid)
116 {
117 /* the source is not recognised */
118
119 if (tracing)
120 {
121 printf("TRACING: invalid source [%s]\n", source_name );
122 }
123
124 if (result->error_str == NULL)
125 {
126 result->error_str = strdup("***Error: No such source");
127 }
128 else
129 {
130 temp = (char *)malloc(strlen(result->error_str)
131 + strlen("***Error: No such source") + 2);
132 sprintf(temp, "%s\n%s", result->error_str,
133 "***Error: No such source");
134 free(result->error_str);
135 result->error_str = temp;
136 }
137 /* and here we have to change the result code of "result" here ... */
138 switch (result->result)
139 {
140 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
141 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
142 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
143 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
144 default: result->result = UP_EXTSYN_ERR; break;
145 }
146 }
147
148 free(source_name);
149 }
150
151
152 /* void up_check_country_attr
153 checks for a valid country in the 'country' attributes */
154 void up_check_country_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
155 {
156 int valid,i, matched ;
157 char *country_name;
158 char *temp;
159 GList *country_list = NULL;
160 GList *country_item = NULL;
161
162 country_list = rpsl_object_get_attr(external_syntax_obj, "country");
163 rpsl_attr_split_multiple(&country_list);
164
165 if ( country_list == NULL )
166 return; /* only check if there is one */
167
168 valid = 1 ;
169 for ( country_item = country_list; country_item != NULL ; country_item = g_list_next(country_item) )
170 {
171 country_name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(country_item->data) );
172 matched = 0 ;
173 i = 0 ;
174 while(countries[i])
175 {
176 if(strcasecmp(countries[i++],country_name) == 0)
177 {
178 matched = 1;
179 break;
180 }
181 }
182
183 if ( ! matched )
184 {
185 valid = 0 ;
186 break;
187 }
188 free(country_name);
189 }
190 g_list_free(country_list);
191
192 if (!valid)
193 {
194 /* the country is not recognised */
195 if (result->error_str == NULL)
196 {
197 result->error_str = malloc(strlen("***Error: No such country []") + strlen(country_name) +2);
198 sprintf(result->error_str, "***Error: No such country [%s]", country_name);
199 }
200 else
201 {
202 temp = (char *)malloc(strlen(result->error_str)
203 + strlen("***Error: No such country []") + strlen(country_name) + 2);
204 sprintf(temp, "%s\n***Error: No such country [%s]", result->error_str,
205 country_name);
206 free(result->error_str);
207 result->error_str = temp;
208 }
209
210 free(country_name);
211
212 /* and here we have to change the result code of "result" here ... */
213 switch (result->result)
214 {
215 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
216 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
217 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
218 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
219 default: ;
220 }
221 }
222 }
223
224 /* void up_check_nicsuffixes
225 checks for a valid suffix at the end of a 'nic-hdl' attributes */
226 void up_check_nicsuffixes(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
227 {
228 int valid,i ;
229 char *name;
230 char *temp;
231 GList *list;
232
233 if (tracing)
234 {
235 printf("TRACING: up_check_nicsuffixes running\n");
236 }
237
238 list = rpsl_object_get_attr(external_syntax_obj, "nic-hdl");
239
240 valid = i = 0 ;
241 if ( list )
242 {
243 name = rpsl_attr_get_clean_value( (rpsl_attr_t *)(list->data) );
244 if ( !strchr(name,'-') || strncasecmp(name,"AUTO-",strlen("AUTO-")) == 0 )
245 {
246 valid = 1;
247 }
248 else
249 {
250 while (nicsuffixes[i])
251 {
252 if ( strcasecmp(nicsuffixes[i++],strchr(name,'-')+1) == 0 )
253 {
254 valid = 1;
255 break;
256 }
257 }
258 if ( ! valid )
259 {
260 i = 0;
261 for ( i=0; i<num_sources; i++ )
262 {
263 if ( ! strcasecmp( upd_source_hdl[i]->name, strchr(name,'-')+1) )
264 {
265 valid = 1;
266 break;
267 }
268 }
269
270 /* while (sources[i])
271 {
272 if (strcasecmp(sources[i++],strchr(name,'-')+1) == 0 )
273 {
274 valid = 1;
275 break;
276 }
277 } */
278
279 if ( ! valid )
280 {
281 i = 0;
282 while (countries[i])
283 {
284 if ( strcasecmp(countries[i++],strchr(name,'-')+1) == 0 )
285 {
286 valid = 1;
287 break;
288 }
289 }
290 }
291 }
292 }
293 free(name);
294 g_list_free(list);
295
296 if (!valid)
297 {
298 /* the nicsuffix is not recognised */
299 if (result->error_str == NULL)
300 {
301 result->error_str = strdup("***Error: Invalid nic-hdl suffix");
302 }
303 else
304 {
305 temp = (char *)malloc(strlen(result->error_str)
306 + strlen("***Error: Invalid nic-hdl suffix") + 2);
307 sprintf(temp, "%s\n%s", result->error_str,
308 "***Error: Invalid nic-hdl suffix");
309 free(result->error_str);
310 result->error_str = temp;
311 }
312 /* and here we have to change the result code of "result" here ... */
313 switch (result->result)
314 {
315 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
316 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
317 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
318 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
319 default: ;
320 }
321 }
322 }
323 }
324
325
326 /* obtains a list of dates in the given
327 list of attributes */
328 GList * up_get_dates(GList * attribute_list)
/* [<][>][^][v][top][bottom][index][help] */
329 {
330 GList * item;
331 char * str, *temp;
332 GList * list = NULL;
333
334 for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
335 {
336 /* is this a 'changed' attribute? */
337 if ( strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0 )
338 {
339 str = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
340
341
342 /* now, we have the 'changed' attribute's content in "normalized" form
343 We are sure it contains a date. So, it must be the second (and last)
344 word in the attrib. */
345 assert(index(str,' ') != NULL);
346 temp = (char *)malloc(strlen(str) - (index(str,' ') - str ));
347 temp = strncpy(temp, index(str,' ') + 1, strlen(str) - (index(str,' ') - str ) - 1);
348 temp[strlen(str) - (index(str,' ') - str ) - 1] = '\0'; /* NULL terminate it */
349 list = g_list_append (list, temp);
350 }
351 }
352
353 return list;
354 }
355
356
357
358
359 /* Does the 'changed' attribute we got have a date already?
360 Returns 1 if it does, 0 if not. */
361 int up_changed_has_date(char * value)
/* [<][>][^][v][top][bottom][index][help] */
362 {
363 /* now, if there is still a white space, then we have a date in the string
364 (it has to be something like "ripe-dbm@ripe.net 20001210") */
365 if (index(value, ' ') != NULL)
366 {
367 return 1;
368 }
369 else
370 {
371 return 0;
372 }
373 }
374
375
376
377
378 /* supplies the current date in YYYYMMDD format (for example 20011010) */
379 char * UP_get_current_date()
/* [<][>][^][v][top][bottom][index][help] */
380 {
381 /* We will use Glib's functions here */
382
383 char * date;
384 struct tm * time_struct;
385
386 time_t * time_loc;
387
388 time_loc = (time_t *)malloc(sizeof(time_t));
389 time(time_loc);
390
391 time_struct = localtime(time_loc);
392
393
394 date = (char *)malloc(9);
395 sprintf(date, "%04i%02i%02i",
396 time_struct->tm_year + 1900,
397 time_struct->tm_mon + 1,
398 time_struct->tm_mday);
399 return date;
400 }
401
402
403
404
405 /* int up_add_dates: adds dates to 'changed' attributes which
406 are missing one.
407 Returns 1 if no problems encountered
408 Returns 0 if a problem encountered, and the error string is set */
409 int up_add_dates(rpsl_object_t *external_syntax_obj, GList *attribute_list, char ** warning_str, char ** error_str)
/* [<][>][^][v][top][bottom][index][help] */
410 {
411 GList * item;
412 char * current_date;
413 int count_no_date = 0;
414 char * temp;
415 rpsl_attr_t *changed;
416 char *value;
417 int pos;
418
419 *warning_str = NULL;
420 *error_str = NULL;
421
422 /* get the current date in YYYYMMDD format (for example 20011010) */
423 current_date = UP_get_current_date();
424
425 for ( item = attribute_list; item != NULL ; item = g_list_next(item) )
426 {
427 /* is this a 'changed' attribute? */
428 if (strcmp(rpsl_attr_get_name((rpsl_attr_t *)(item->data)), "changed") == 0)
429 {
430 /* if this attribute does not have a date in it, add it. Also add
431 a warning message about this */
432 value = rpsl_attr_get_clean_value((rpsl_attr_t *)(item->data));
433 if ( !up_changed_has_date(value) )
434 {
435 count_no_date++;
436 /* create a copy of this changed attribute and add the date to the value */
437 changed = rpsl_attr_copy((rpsl_attr_t *)(item->data));
438 temp = (char *)malloc(strlen(value) + strlen(current_date) + 2 );
439 sprintf(temp, "%s %s", value, current_date);
440 rpsl_attr_replace_value(changed, temp);
441 free(temp);
442 /* delete the original attribute from the object */
443 pos = rpsl_attr_get_ofs(changed);
444 rpsl_object_remove_attr(external_syntax_obj, pos, NULL);
445 /* add the new changed attribute in the same position */
446 rpsl_object_add_attr(external_syntax_obj, changed, pos, NULL);
447 /* add a warning message */
448 if ( *warning_str == NULL)
449 {
450 *warning_str = (char *)malloc(strlen("WARNING date '' added to 'changed' attribute") + 9 );
451 sprintf(*warning_str, "WARNING date '%s' added to 'changed' attribute", current_date);
452 }
453 else
454 {
455 temp = (char *)malloc(strlen(*warning_str) + 1
456 + strlen("WARNING date '' added to 'changed' attribute") + 9 );
457 sprintf(temp, "%s\nWARNING date '%s' added to 'changed' attribute",
458 *warning_str, current_date);
459 free(*warning_str);
460 *warning_str = temp;
461 }
462 }
463 free(value);
464 }
465 }
466
467 if (count_no_date > 1)
468 {
469 *error_str = strdup("***Error: More than one 'changed' attributes without dates");
470 return 0;
471 }
472 else
473 {
474 return 1;
475 }
476 }
477
478
479
480
481 /* Checks the order of dates in the given list.
482 If they are in order, returns 1,
483 if not, returns 0 */
484 int up_check_date_order(GList * list)
/* [<][>][^][v][top][bottom][index][help] */
485 {
486 GList * item;
487 char * previous;
488 char *value;
489
490 /* if list is empty, return 1 immediately */
491 if (list == NULL)
492 {
493 return 1;
494 }
495
496 /* initialize the 'previous' date */
497 previous = strdup("00000000");
498
499 for ( item = list; item != NULL ; item = g_list_next(item))
500 {
501 assert((item->data) != NULL);
502 /* if the new date is smaller than the previous */
503 value = (char *)(item->data);
504 if ( strcmp(value, previous) < 0 )
505 {
506 free(previous);
507 return 0;
508 }
509 free(previous);
510 previous = strdup(value);
511 }
512
513 free(previous);
514 /* Reached the end, without finding out-of-order date. Return 1, then */
515 return 1;
516 }
517
518
519
520
521
522 /* up_check_date: checks the syntax of the date, given as the only
523 argument (char *). The argument is checked if it is in YYYYMMDD
524 format, and returns an error code accordingly */
525 int up_check_date(const char * arg)
/* [<][>][^][v][top][bottom][index][help] */
526 {
527 int date_int; /* integer representation of the date (arg) */
528 char * current_date;
529 int year, month, day; /* integers for the components of the date */
530
531 errno = 0;
532 date_int = atoi(arg);
533
534 if (errno != 0)
535 { /* there was an error in the conversion, syntax error */
536 return UP_DATE_SYNERR;
537 }
538
539 /* wrong format */
540 if (date_int <= 10000000 )
541 { /* the date is not in YYYYMMDD format */
542 return UP_DATE_WRONGFORMAT;
543 }
544
545 /* check if it is too small */
546 if (date_int <= 19840000 )
547 { /* the date is older than the DB itself! */
548 return UP_DATE_TOOSMALL;
549 }
550
551 /* check if it is too big */
552 if (date_int >= 100000000 )
553 {/* too big: syntax error */
554 return UP_DATE_SYNERR;
555 }
556
557 /* and now check year, month and day components */
558 year = date_int / 10000;
559 month = (date_int - (year * 10000) ) / 100;
560 day = (date_int % 100);
561
562 /* check year */
563 if (year < 1984 )
564 {
565 return UP_DATE_TOOSMALL;
566 }
567
568 /* check month */
569 if (month < 1 || month > 12)
570 {
571 return UP_DATE_INVMONTH;
572 }
573
574 /* check day */
575 if (day < 1 || day > 31)
576 {
577 return UP_DATE_INVDAY;
578 }
579
580 switch ( month )
581 {
582 case 1: case 3: case 5: case 7:
583 case 8: case 10: case 12:
584 if (day > 31)
585 {
586 return UP_DATE_INVDAY;
587 };
588 break;
589 case 2:
590 if ( (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) && (day > 29 ))
591 { /* leap year */
592 return UP_DATE_INVDAY;
593 }
594 else if( (!(year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))) && (day > 28) )
595 { /* non-leap year */
596 return UP_DATE_INVDAY;
597 };
598 break;
599 case 4: case 6: case 9: case 11:
600 if (day > 30)
601 {
602 return UP_DATE_INVDAY;
603 };
604 break;
605 default: return UP_DATE_INVMONTH;
606 }
607
608 /* check if the arg is in the future or not */
609 current_date = UP_get_current_date();
610 if (strcmp(current_date, arg) < 0 )
611 { /* arg is in the future */
612 free(current_date);
613 return UP_DATE_FUTURE;
614 }
615 free(current_date);
616
617 return UP_DATE_OK;
618 }
619
620
621
622 /* Checks the syntax of the dates in the list */
623 date_syntax_struct * up_check_dates_syntax(GList * list)
/* [<][>][^][v][top][bottom][index][help] */
624 {
625 GList * item;
626 date_syntax_struct * result;
627 int res;
628
629 /* initialize the result struct */
630 result = (date_syntax_struct *)malloc(sizeof(date_syntax_struct));
631 result->result = UP_DATE_OK;
632 result->error_str = NULL;
633
634 /* if list is empty, return immediately */
635 if (list == NULL)
636 {
637 return result;
638 }
639
640 /* loop through the members of the list, check each of them */
641 for ( item = list; item != NULL ; item = g_list_next(item))
642 {
643 assert((item->data) != NULL);
644
645 /* check the date */
646 res = up_check_date((char *)(item->data));
647 switch (res)
648 {
649 case UP_DATE_OK: break;
650
651 case UP_DATE_FUTURE:
652 case UP_DATE_TOOSMALL:
653 case UP_DATE_INVDAY:
654 case UP_DATE_INVMONTH:
655 case UP_DATE_WRONGFORMAT:
656
657 if (result->error_str == NULL)
658 {
659 result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[res])
660 + strlen(": ") + strlen((char *)(item->data)) + 1);
661 sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[res],
662 (char *)(item->data));
663 }
664 else
665 {
666 result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
667 + strlen("***Error: ") + strlen(up_date_errmsgs[res])
668 + strlen(": ") + strlen((char *)(item->data)) + 1);
669 sprintf(result->error_str, "%s\n***Error: %s: %s",
670 result->error_str, up_date_errmsgs[res], (char *)(item->data));
671 }
672 result->result = UP_DATE_NOK; /* Not OK */
673
674 break;
675
676
677 case UP_DATE_SYNERR: /* syntax error in the date */
678
679 default:
680 if (result->error_str == NULL)
681 {
682 result->error_str = (char *)malloc(strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
683 + strlen(": ") + strlen((char *)(item->data)) + 1);
684 sprintf(result->error_str, "***Error: %s: %s", up_date_errmsgs[UP_DATE_SYNERR],
685 (char *)(item->data));
686 }
687 else
688 {
689 result->error_str = (char *)realloc(result->error_str, strlen(result->error_str) + 1
690 + strlen("***Error: ") + strlen(up_date_errmsgs[UP_DATE_SYNERR])
691 + strlen(": ") + strlen((char *)(item->data)) + 1);
692 sprintf(result->error_str, "%s\n***Error: %s: %s",
693 result->error_str, up_date_errmsgs[UP_DATE_SYNERR], (char *)(item->data));
694 }
695 result->result = UP_DATE_NOK; /* Not OK */
696 break;
697 }
698 }
699
700 return result;
701 }
702
703
704
705 /* void up_check_changed_attr
706 checks the order of dates in the 'changed' attributes */
707 void up_check_changed_attr(rpsl_object_t *external_syntax_obj, external_syntax_struct * result)
/* [<][>][^][v][top][bottom][index][help] */
708 {
709 GList * date_list;
710 int res;
711 char ** warning, **error;
712 char * temp;
713 date_syntax_struct * date_check_res;
714 GList *changed_list;
715
716 warning = (char **)malloc(sizeof(char **));
717 error = (char **)malloc(sizeof(char **));
718 changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
719
720 /* Now, add dates to the "changed" attributes */
721 res = up_add_dates(external_syntax_obj, changed_list, warning, error);
722 if (!res)
723 {
724 /* so, add the error string to result's error string */
725 if (result->error_str == NULL)
726 {
727 result->error_str = strdup(*error);
728 }
729 else
730 {
731 temp = (char *)malloc(strlen(result->error_str) + strlen(*error) + 2);
732 sprintf(temp, "%s\n%s", result->error_str, *error);
733 free(result->error_str);
734 result->error_str = temp;
735 }
736 }
737
738 /* and get the list of dates, we must check their order */
739 /* we may have added a date to one of the changed attrs so get the list again */
740 rpsl_attr_delete_list(changed_list);
741 changed_list = rpsl_object_get_attr(external_syntax_obj, "changed");
742 date_list = up_get_dates(changed_list);
743 /* and check the order */
744 res = up_check_date_order(date_list);
745 if (!res)
746 {
747 /* so, add the error string to result's error string */
748 if (result->error_str == NULL)
749 {
750 result->error_str = strdup("***Error: The dates in the 'changed' attributes should be in order");
751 }
752 else
753 {
754 temp = (char *)malloc(strlen(result->error_str)
755 + strlen("***Error: The dates in the 'changed' attributes should be in order") + 2);
756 sprintf(temp, "%s\n%s", result->error_str,
757 "***Error: The dates in the 'changed' attributes should be in order");
758 free(result->error_str);
759 result->error_str = temp;
760 }
761 /* and here we have to change the result code of "result" here ... */
762 switch (result->result)
763 {
764 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
765 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
766 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
767 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
768 default: ;
769 }
770 }
771
772 /* check the syntax of dates */
773 date_check_res = up_check_dates_syntax(date_list);
774 if (date_check_res->result != UP_DATE_OK)
775 {
776 /* so, add the error string to result's error string */
777 if (result->error_str == NULL)
778 {
779 result->error_str = strdup(date_check_res->error_str);
780 }
781 else
782 {
783 temp = (char *)malloc(strlen(result->error_str)
784 + strlen(date_check_res->error_str) + 2);
785 sprintf(temp, "%s\n%s", result->error_str,
786 date_check_res->error_str);
787 free(result->error_str);
788 result->error_str = temp;
789 }
790 /* and here we have to change the result code of "result" here ... */
791 switch (result->result)
792 {
793 case UP_EXTSYN_OK: result->result = UP_EXTSYN_ERR; break;
794 case UP_EXTSYN_ERR: result->result = UP_EXTSYN_ERR; break;
795 case UP_EXTSYN_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
796 case UP_EXTSYN_ERR_WARN: result->result = UP_EXTSYN_ERR_WARN; break;
797 default: ;
798 }
799 }
800 }
801
802
803 /* performs a simple check on a inetnum attribute. Assumes that
804 the RPSL parser has already checked it. Tries to see if the attr
805 is a range or not */
806 int up_check_an_inetnum_attr(const char * arg){
/* [<][>][^][v][top][bottom][index][help] */
807
808
809 char * str;
810 char * pos;
811
812 str = strdup(arg);
813
814 while((pos = index(str, '\n')) != NULL){
815 *pos = ' ';
816 }
817
818 /* strip off the comment */
819 if((pos = index(str, '#')) != NULL){
820 *pos = '\0';
821 }
822
823
824 /* Most of the syntax check is done by RPSL parser. We only need to check
825 that the argument is a _range_ of IPv4 addresses. So it suffices to
826 check the existence of '-' in the arg */
827 if(index(str, '-') != NULL){
828
829 free(str);
830 return 1;
831
832 }else{
833
834 free(str);
835 return 0;
836
837 }
838 }
839
840
841 /* void up_add_keycert_attrs
842 adds the generated attrs of key-cert objects */
843 void up_add_keycert_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
844 {
845 const char *type;
846 char *attr_str;
847 rpsl_attr_t *method_attr;
848 rpsl_attr_t *owner_attr;
849 rpsl_attr_t *fingerpr_attr;
850
851 if (tracing)
852 {
853 printf("TRACING: UP_add_keycert_attrs: is running\n");
854 }
855
856 /* if this is a key-cert object */
857 type = rpsl_object_get_class(generated_obj);
858 if ( strcmp(type, "key-cert") == 0 )
859 {
860 method_attr = rpsl_attr_init("method: PGP", type);
861 if ( method_attr )
862 {
863 rpsl_object_add_attr(generated_obj, method_attr, 1, NULL);
864 }
865
866 attr_str = (char *)malloc( sizeof("owner: ") + strlen(keyowner) +1 );
867 strcpy(attr_str, "owner: ");
868 strcat(attr_str, keyowner);
869 if (tracing)
870 {
871 printf("TRACING: UP_add_keycert_attrs: owner attr_str [%s]\n", attr_str);
872 }
873 owner_attr = rpsl_attr_init(attr_str, "key-cert");
874 if ( owner_attr )
875 {
876 rpsl_object_add_attr(generated_obj, owner_attr, 2, NULL);
877 }
878 free(attr_str);
879
880 attr_str = (char *)malloc( sizeof("fingerpr: ") + strlen(fingerprint) +1 );
881 strcpy(attr_str, "fingerpr: ");
882 strcat(attr_str, fingerprint);
883 if (tracing)
884 {
885 printf("TRACING: UP_add_keycert_attrs: fingerprint attr_str [%s]\n", attr_str);
886 }
887 fingerpr_attr = rpsl_attr_init(attr_str, "key-cert");
888 if ( fingerpr_attr )
889 {
890 rpsl_object_add_attr(generated_obj, fingerpr_attr, 3, NULL);
891 }
892 free(attr_str);
893 }
894 }
895
896
897 /* up_reconstruct_object: Reconstructs the object's text representation
898 using the parsed object */
899 void up_reconstruct_object(rpsl_object_t *external_syntax_obj, external_syntax_struct *result)
/* [<][>][^][v][top][bottom][index][help] */
900 {
901 char * recons_obj = NULL;
902
903 recons_obj = rpsl_object_get_text(external_syntax_obj,RPSL_STD_COLUMN);
904
905 result->new_obj = recons_obj;
906 }
907
908
909
910 /* UP_check_external_syntax: Checks the syntax of attributes which are not checked
911 by the api parser module. */
912 external_syntax_struct * UP_check_external_syntax(rpsl_object_t *external_syntax_obj)
/* [<][>][^][v][top][bottom][index][help] */
913 {
914 external_syntax_struct *result;
915
916 if (tracing)
917 {
918 printf("TRACING: UP_check_external_syntax running\n");
919 }
920
921 result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
922
923 /* initialize the struct */
924 result->result = 0;
925 result->error_str = strdup("");
926 result->warning_str = strdup("");
927
928 up_check_source_attr(external_syntax_obj, result);
929
930 up_check_country_attr(external_syntax_obj, result);
931
932 up_check_nicsuffixes(external_syntax_obj, result);
933
934 up_check_changed_attr(external_syntax_obj, result);
935
936 up_reconstruct_object(external_syntax_obj, result);
937
938 if (tracing)
939 {
940 printf("TRACING: UP_check_external_syntax: the reconstructed object is=[%s]\n", result->new_obj);
941 printf("TRACING: UP_check_external_syntax: ... and the result code is=[%i]\n", result->result);
942 }
943
944 return result;
945 }
946
947
948
949 /* generates the "generated" attributes of a key-cert object. Returns the
950 new object string*/
951 char *UP_generate_kc_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
952 {
953 external_syntax_struct *result;
954 char *obj_str;
955
956 if (tracing)
957 {
958 printf("TRACING: UP_generate_kc_attrs: is running\n");
959 }
960
961 result = (external_syntax_struct *)malloc(sizeof(external_syntax_struct));
962
963 /* initialize the struct */
964 result->result = 0;
965 result->error_str = strdup("");
966 result->warning_str = strdup("");
967
968 up_check_changed_attr(generated_obj, result);
969 up_add_keycert_attrs(generated_obj);
970
971 up_reconstruct_object(generated_obj, result);
972
973 if (tracing)
974 {
975 printf("TRACING: UP_generate_kc_attrs: the reconstructed object is=[%s]\n", result->new_obj);
976 printf("TRACING: UP_generate_kc_attrs: ... and the result code is=[%i]\n", result->result);
977 }
978
979 obj_str = strdup(result->new_obj);
980 free(result);
981 return obj_str;
982 }
983
984
985
986 /* char * up_assign_i6_status: Determines the status attribute of
987 an inet6num object. It takes the inet6num attribute of the
988 object as its only argument. If prefix length is less than
989 4, then returns NULL */
990 char * up_assign_i6_status(const char * inet6num_attr)
/* [<][>][^][v][top][bottom][index][help] */
991 {
992
993 char ** split_str;
994 int prefix_length;
995 int result;
996
997 /* we need the prefix length here.*/
998 split_str = g_strsplit(inet6num_attr, "/", 0);
999 if(split_str[1] != NULL){
1000
1001 result = sscanf(split_str[1], "%i", &prefix_length);
1002 if(result != 0 && result != EOF){
1003
1004 if(prefix_length >= 0 && prefix_length <= 3){
1005
1006 g_strfreev(split_str);
1007 return NULL;
1008
1009 }else if(prefix_length >= 4 && prefix_length <= 15){
1010
1011 g_strfreev(split_str);
1012 return strdup("TLA");
1013
1014 }else if(prefix_length >= 16 && prefix_length <= 35){
1015
1016 g_strfreev(split_str);
1017 return strdup("SUBTLA");
1018
1019 }else if(prefix_length >= 36 && prefix_length <= 48){
1020
1021 g_strfreev(split_str);
1022 return strdup("NLA");
1023
1024 }else if(prefix_length >= 48 && prefix_length <= 64){
1025
1026 g_strfreev(split_str);
1027 return strdup("SLA");
1028
1029 }else{
1030
1031 /* "default" status */
1032 g_strfreev(split_str);
1033 return strdup("SLA");
1034
1035 }
1036
1037 }else{
1038
1039 /* return "default" status */
1040 g_strfreev(split_str);
1041 return strdup("SLA");
1042
1043 }
1044 }else{
1045
1046 /* return "default" status */
1047 g_strfreev(split_str);
1048 return strdup("SLA");
1049
1050 }
1051
1052 }
1053
1054
1055
1056 /* GSList * up_add_inet6num_attrs
1057 adds the generated attrs of inet6num objects */
1058 /*GSList * up_add_inet6num_attrs(Object * obj, char * obj_text, GSList * attribute_list,
1059 external_syntax_struct * result)*/
1060 void up_add_inet6num_attrs(rpsl_object_t *generated_obj)
/* [<][>][^][v][top][bottom][index][help] */
1061 {
1062
1063 int attribute_no;
1064 char *status_value;
1065 rpsl_attr_t * status_attr;
1066 char *inet6num_attr_str, *status_attr_str;
1067 const char *type;
1068 GList *attributes_changed;
1069
1070
1071
1072 /* if this is an inet6num object */
1073 type = rpsl_object_get_class(generated_obj);
1074 if( ! strcmp(type, "inet6num") )
1075 {
1076 inet6num_attr_str = get_search_key(generated_obj, "inet6num");
1077 status_value = up_assign_i6_status(inet6num_attr_str);
1078 status_attr_str = (char *)UT_malloc(strlen("status: ") + strlen(status_value) + 1);
1079 strcpy(status_attr_str, "status: ");
1080 strcat(status_attr_str, status_value);
1081 status_attr = rpsl_attr_init(status_attr_str, type);
1082 free(status_attr_str);
1083 if ( status_attr )
1084 {
1085 /* we will put the status attribute before the first 'changed' attribute */
1086 attribute_no = 1; /* a default position (the second attribute) in case we cannot find
1087 a 'changed' attribute */
1088 attributes_changed = rpsl_object_get_attr(generated_obj, "changed");
1089 if ( attributes_changed != NULL )
1090 {
1091 attribute_no = ((rpsl_attr_t *)(attributes_changed->data))->num;
1092 }
1093 rpsl_object_add_attr(generated_obj, status_attr, attribute_no, NULL);
1094 }
1095 }
1096 }
1097