Source File modules/ud/ud_main.c

    1    | /***************************************
    2    |   $Revision: 1.12 $
    3    |
    4    |   Wrapper for NRTM client
    5    |
    6    |   Status: NOT REVUED, NOT TESTED
    7    |
    8    |  Author(s):       Andrei Robachevsky
    9    |
    10   |   ******************/ /******************
    11   |   Modification History:
    12   |         andrei (17/01/2000) Created.
    13   |   ******************/ /******************
    14   |   Copyright (c) 2000                              RIPE NCC
    15   |
    16   |   All Rights Reserved
    17   |
    18   |   Permission to use, copy, modify, and distribute this software and its
    19   |   documentation for any purpose and without fee is hereby granted,
    20   |   provided that the above copyright notice appear in all copies and that
    21   |   both that copyright notice and this permission notice appear in
    22   |   supporting documentation, and that the name of the author not be
    23   |   used in advertising or publicity pertaining to distribution of the
    24   |   software without specific, written prior permission.
    25   |
    26   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
    27   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
    28   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
    29   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
    30   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    31   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    32   |  ***************************************/
    33   | #include <sys/types.h>
    34   | #include <fcntl.h>
    35   | #include <signal.h>
    36   | #include "ud.h"
    37   | #include "ud_int.h"
    38   | #include "constants.h"
    39   | #include "server.h"
    40   | #include "protocol_mirror.h"
    41   |
    42   |
    43   | /* Response time to swtching updates on and off */
    44   | #define TIMEOUT 60
    45   |
    46   |
    47   | int get_current_serial()
    48   | {
    49   |  int fd;
    50   |  char buff[64];
    51   |  const char *filename;
    52   |
    53   |  filename=CO_get_nrtm_cserialfile();
    54   |  fd=open(filename, O_RDONLY, (mode_t)0);
    55   |  if (fd < 0) { fprintf(stderr, "cannot open %s\n", filename); return(-1); }
    56   |  read(fd, buff, sizeof(buff));
    57   |  close(fd);
    58   |  return(atoi(buff));
    59   | }
    60   |
    61   | int set_current_serial(int current_serial)
    62   | {
    63   | FILE *file;
    64   | const char *filename;
    65   |
    66   |  filename=CO_get_nrtm_cserialfile();
    67   |  file=fopen(filename, "w+");
    68   |  if (file==NULL) { fprintf(stderr, "cannot open %s\n", filename); return(-1); }
    69   |  fprintf(file,"%d\n", current_serial);
    70   |  fflush(file);
    71   |  fclose(file);
    72   |  return(current_serial);
    73   | }
    74   |
    75   |
    76   | /*************************************
    77   | *
    78   | *
    79   | **************************************/
    80   |
    81   | void UD_do_nrtm()
    82   | {
    83   | UD_stream_t ud_stream;
    84   | struct _nrtm *nrtm;
    85   | /*int dummy_allowed;*/
    86   | int delay;
    87   | int do_update=1;
    88   | int do_server;
    89   | const char *logfilename;
    90   | FILE *file;
    91   | int num_ok;
    92   | int upto_last;
    93   | int current_serial;
    94   |
    95   |   nrtm=calloc(1, sizeof(struct _nrtm));
    96   |   if(nrtm==NULL) {
    97   | 	  printf("Cannot allocate memory\n");
    98   | 	  die;
    99   |   }
    100  | /* get mode of operation: protected/unprotected (dummy) */
    101  |   ud_stream.ud_mode=CO_get_update_mode();
    102  |
    103  |   fprintf(stderr, "Mode of operation:\n");
    104  |   if(IS_DUMMY_ALLOWED(ud_stream.ud_mode))fprintf(stderr, "* dummy allowed\n");
    105  |    else fprintf(stderr, "* dummy not allowed\n");
    106  |   if(IS_UPDATE(ud_stream.ud_mode))fprintf(stderr, "* DBupdate\n");
    107  |    else fprintf(stderr, "* NRTM\n");
    108  |   if(IS_STANDALONE(ud_stream.ud_mode))fprintf(stderr, "* running standalone\n");
    109  |    else fprintf(stderr, "* running as a server\n");
    110  |
    111  | /* get mirror server */
    112  |   nrtm->server=CO_get_nrtm_host();
    113  |
    114  | /* get mirror port */
    115  |   nrtm->port = SK_atoport(CO_get_nrtm_port(), "tcp");
    116  |   printf("XXX nrtm_port=%d\n", nrtm->port);
    117  |   if(nrtm->port == -1) {
    118  |     printf("Invalid service/port: %d\n", nrtm->port);
    119  |     return;
    120  |   }
    121  |
    122  | /* get mirror version */
    123  |   nrtm->version=CO_get_nrtm_version();
    124  |
    125  | /* get error log facility */
    126  |   logfilename=CO_get_nrtm_logfile();
    127  |
    128  | /* Connect to the database */
    129  |   fprintf(stderr, "D: Making SQL connection to %s@%s ...", CO_get_database(), CO_get_host());
    130  |
    131  |   ud_stream.db_connection=SQ_get_connection2();
    132  |
    133  |   if(! ud_stream.db_connection) {
    134  |    fprintf(stderr, "D: ERROR: no SQL connection\n");
    135  |     return;
    136  |   }
    137  |
    138  |   fprintf(stderr, "OK\n");
    139  |
    140  |
    141  |
    142  | /*  ud_stream.dummy_allowed=dummy_allowed;*/
    143  |   ud_stream.num_skip=0;
    144  |   ud_stream.load_pass=0;
    145  |   ud_stream.nrtm=nrtm;
    146  |
    147  |   upto_last=0; /* let's start gradually if the backlog is > SBUNCH (1000) serials*/
    148  |
    149  | /*+++ main cycle +++*/
    150  |
    151  |  do {
    152  |   do_update=CO_get_do_update();
    153  |   if(do_update) {
    154  |
    155  |
    156  |   /* get current serial */
    157  |    current_serial=get_current_serial();
    158  |    nrtm->current_serial=PM_get_current_serial(ud_stream.db_connection);
    159  |
    160  |    if(nrtm->current_serial == -1) {
    161  |      printf("Error obtaining current serial: %ld(%d)\n", nrtm->current_serial, current_serial);
    162  |      return;
    163  |    }
    164  |
    165  |    fprintf(stderr, "current_serial:\t%ld(%d)\n", nrtm->current_serial, current_serial);
    166  |    fprintf(stderr, "conecting to server...\n");
    167  |
    168  |
    169  |     file = get_NRTM_stream(nrtm, upto_last);
    170  |     fprintf(stderr, "OK\n");
    171  |     printf("OK\n");
    172  |
    173  |
    174  |     if (file==NULL) {
    175  |      fprintf(stderr, "Cannot open data stream. Trying...\n");
    176  |      sleep(100);
    177  |      continue;
    178  |     }
    179  |
    180  |
    181  |    ud_stream.stream=file;
    182  |    ud_stream.log.logfile = fopen(logfilename, "a+");
    183  |    ud_stream.log.num_ok=0;
    184  |    ud_stream.log.num_failed=0;
    185  |
    186  |
    187  |    fprintf(stderr, "starting processing stream\n");
    188  |
    189  |    num_ok=UD_process_stream(&ud_stream);
    190  |
    191  |
    192  |      /*Check for errors */
    193  |    if(num_ok<0) {
    194  | 	 fprintf(stderr, "processing stream failed\n");
    195  | 	 do_server=0;
    196  | 	 break;
    197  |    }
    198  |    else fprintf(stderr, "processing stream finished\n");
    199  |
    200  |   /* Now we can process serials in normal way (upto LAST)*/
    201  |    if(num_ok==0) upto_last=1;
    202  |
    203  | /* This is for test purposes, just to know if we are out of sync */
    204  |    set_current_serial((int)(current_serial+num_ok));
    205  |    fprintf(ud_stream.log.logfile, "forwarded to serial:\t%ld(%d)\n", (nrtm->current_serial+num_ok), current_serial+num_ok);
    206  |    fclose(ud_stream.log.logfile);
    207  |    fprintf(stderr, "forwarded to serial:\t%ld(%d)\n", (nrtm->current_serial+num_ok), current_serial+num_ok);
    208  |    printf("Objects received: %d\n-----------\n", num_ok);
    209  |
    210  |   /* get delay */
    211  |    delay=CO_get_nrtm_delay();
    212  |    SV_sleep(LOCK_SHTDOWN, delay);
    213  |   }
    214  |  else SV_sleep(LOCK_SHTDOWN, TIMEOUT);
    215  |
    216  |   do_server=CO_get_do_server();
    217  |
    218  |  } while(do_server);  /* main cycle */
    219  |
    220  |  if(nrtm) free(nrtm);
    221  |  /* That's all. Close connection to the DB */
    222  |  SQ_close_connection(ud_stream.db_connection);
    223  |  fprintf(stderr, "NRTM stopped\n");
    224  |
    225  | } /* UD_do_nrtm() */
    226  |
    227  |
    228  |
    229  |
    230  | /*************************************
    231  | *
    232  | *
    233  | **************************************/
    234  |
    235  | void UD_do_updates(void *arg)
    236  | {
    237  | int listening_socket = (int)arg;
    238  | int connected_socket;
    239  | UD_stream_t ud_stream;
    240  | int do_update=1;
    241  | int do_server;
    242  | const char *logfilename;
    243  | FILE *file, *file_ack;
    244  | int num_ok;
    245  |
    246  |
    247  | /* get mode of operation: protected/unprotected (dummy) */
    248  |   ud_stream.ud_mode=CO_get_update_mode();
    249  |
    250  |   fprintf(stderr, "Mode of operation:\n");
    251  |   if(IS_DUMMY_ALLOWED(ud_stream.ud_mode))fprintf(stderr, "* dummy allowed\n");
    252  |    else fprintf(stderr, "* dummy not allowed\n");
    253  |   if(IS_UPDATE(ud_stream.ud_mode))fprintf(stderr, "* DBupdate\n");
    254  |    else fprintf(stderr, "* NRTM\n");
    255  |   if(IS_STANDALONE(ud_stream.ud_mode))fprintf(stderr, "* running standalone\n");
    256  |    else fprintf(stderr, "* running as a server\n");
    257  |
    258  |
    259  |
    260  |
    261  | /* get error log facility */
    262  |   logfilename=CO_get_nrtm_logfile();
    263  |
    264  | /* Connect to the database */
    265  |   fprintf(stderr, "D: Making SQL connection to %s@%s ...", CO_get_database(), CO_get_host());
    266  |
    267  |   ud_stream.db_connection=SQ_get_connection2();
    268  |
    269  |   if(! ud_stream.db_connection) {
    270  |    fprintf(stderr, "D: ERROR: no SQL connection\n");
    271  |     return;
    272  |   }
    273  |
    274  |   fprintf(stderr, "OK\n");
    275  |
    276  |   ud_stream.num_skip=0;
    277  |   ud_stream.load_pass=0;
    278  |   ud_stream.nrtm=NULL;
    279  |
    280  | /*+++ main cycle +++*/
    281  |
    282  | do { /* be alive while do_server is 1. do_server is turned off by SIGINT */
    283  |
    284  | /* accept connection */
    285  |    connected_socket = SK_accept_connection(listening_socket);
    286  |    if(connected_socket==-1) break;
    287  |
    288  |    file=fdopen(connected_socket, "r");
    289  |    file_ack=fdopen(connected_socket, "w");
    290  |
    291  |  do_update=CO_get_do_update();
    292  |  if(do_update) {
    293  |
    294  |    fprintf(stderr, "Connection accepted...\n");
    295  |
    296  |   if ((file==NULL) || (file_ack==NULL)) {
    297  |     fprintf(stderr, "Cannot open data stream. Closing connction\n");
    298  |     return;
    299  |   }
    300  |   fprintf(stderr, "Connection accepted...\n");
    301  |
    302  |   ud_stream.stream=file;
    303  |   ud_stream.log.logfile = fopen(logfilename, "a+");
    304  |   ud_stream.log.num_ok=0;
    305  |   ud_stream.log.num_failed=0;
    306  |
    307  |
    308  |   fprintf(stderr, "starting processing object\n");
    309  |
    310  |   num_ok=UD_process_stream(&ud_stream);
    311  |
    312  |   fprintf(stderr, "processing object finished\n");
    313  |
    314  |   if(num_ok==1) {
    315  |    fprintf(file_ack, "%%ERROR 0\n");
    316  |    fprintf(stderr, "%%ERROR 0\n");
    317  |   }
    318  |    else {
    319  |       num_ok=(-1)*num_ok;
    320  |       fprintf(file_ack, "%%ERROR %d\n",num_ok);
    321  |       fprintf(stderr, "%%ERROR %d\n",num_ok);
    322  |       fprintf(file_ack, "Transaction had the following problems:\n");
    323  |       if(num_ok & ERROR_U_MEM) fprintf(file_ack, "Memory allocation error\n");
    324  | /*      if(num_ok & ERROR_U_DBS) fprintf(file_ack, "Database (SQL) error\n");*/
    325  | /*      if(num_ok & ERROR_U_OBJ) fprintf(file_ack, "Object (RF) error\n");*/
    326  | /*      if(num_ok & ERROR_U_AUT) fprintf(file_ack, "Object authentication error\n");*/
    327  |       if(num_ok & ERROR_U_BADOP) fprintf(file_ack, "Bad operation\n");
    328  |       if(num_ok & ERROR_U_COP) fprintf(file_ack, "Conflicting operation\n");
    329  |       if(num_ok & ERROR_U_NSUP) fprintf(file_ack, "Object of this type is not supported\n");
    330  |       if(num_ok & ERROR_U_BUG) fprintf(file_ack, "Software bug - report to <ripe-dbm@ripe.net>\n");
    331  |    }
    332  |    if(ud_stream.error_script)fprintf(file_ack, "%s\n", ud_stream.error_script);
    333  |
    334  |    if(ud_stream.error_script) free(ud_stream.error_script);
    335  |    fclose(file_ack);
    336  |    fclose(file);
    337  |    fclose(ud_stream.log.logfile);
    338  |
    339  |  }  /* if do_update*/
    340  | else { /* Otherwise print a message*/
    341  |  fprintf(file_ack, "%%ERROR 1000\n%%Updates are suspended\n");
    342  |  fclose(file_ack);
    343  |  fclose(file);
    344  | }
    345  |
    346  |   do_server=CO_get_do_server();
    347  |
    348  | } while (do_server);  /* main cycle */
    349  |
    350  |  /* That's all. Close connection to the DB */
    351  |  SQ_close_connection(ud_stream.db_connection);
    352  |
    353  |  fprintf(stderr, "server stopped\n");
    354  |
    355  | } /* UD_do_update() */
    356  |
    357  |
    358  |
    359  |