## modules/ud/ud_main.c

/* [<][>][^][v][top][bottom][index][help] */

## FUNCTIONS

This source file includes following functions.

1. get_NRTM_fd
2. UD_do_nrtm
3. UD_do_updates

       1 /***************************************
       2   $Revision: 1.40 $
       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,2001,2002                      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 "rip.h"
      35
      36 #include <sys/types.h>
      37 #include <sys/socket.h>
      38 #include <netinet/in.h>
      39 #include <arpa/inet.h>
      40 #include <fcntl.h>
      41 #include <signal.h>
      42 #include <sys/poll.h>
      43
      44
      45 /* here we store sockets for update threads */
      46 /* they are from SV module */
      47 extern int SV_update_sock[];
      48
      49 /* here is the shutdown pipe for update threads */
      50 /* also from SV module (apologies for breaking encapsulation) */
      51 extern int SV_shutdown_recv_fd;
      52
      53 /* Response time to swtching updates on and off */
      54 #define TIMEOUT 60
      55
      56 /* timeout between successive attempts to establish connection with server */
      57 #define PM_CONNECTION_TIMEOUT 10
      58
      59 /* Maximum number of objects(serials) we can consume at a time */
      60 #define SBUNCH 1000
      61
      62 /* Timeout in seconds when reading (writing) from DBupdate */
      63 #define STREAM_TIMEOUT 120
      64
      65 /************************************************************
      66 * int get_NRTM_fd()                                         *
      67 *                                                           *
      68 * Gets the NRTM stream                                      *
      69 *                                                           *
      70 * First tries to request the serials from the NRTM server   *
      71 * If the name of the server appears to be not a network name*
      72 * it tries to open the file with this name                  *
      73 *                                                           *
      74 * nrtm - pointer to _nrtm structure                         *
      75 * upto_last - if==1 then requests to download serials using *
      76 * LAST keyword                                              *
      77 *                                                           *
      78 * Returns:                                                  *
      79 * A file descriptor for a data stream                       *
      80 * -1 - error                                                *
      81 *                                                           *
      82 ************************************************************/
      83 int get_NRTM_fd(struct _nrtm *nrtm, int upto_last, char *source)
         /* [<][>][^][v][top][bottom][index][help] */
      84 {
      85 int sockfd;
      86 struct hostent *hptr;
      87 struct sockaddr_in serv_addr;
      88 struct in_addr *paddr;
      89 char host_info[STR_XXL];
      90 GString *line_buff;
      91 int fd;
      92 int ret;
      93 struct hostent result;
      94 int error;
      95 int network;
      96
      97 /* fprintf(stderr, "Making connection to NRTM server ...\n");*/
      98  if ((sockfd=socket(AF_INET, SOCK_STREAM, 0))==-1){
      99    ER_perror(FAC_UD, UD_FS, "cannot create socket");
     100    return(-1);
     101  }
     102 #ifdef __linux__
     103  if(gethostbyname_r(nrtm->server,  &result, host_info, sizeof(host_info), &hptr, &error)<0)  hptr=NULL;
     104 #else/* default is Solaris implementation */
     105  hptr=gethostbyname_r(nrtm->server,  &result, host_info, sizeof(host_info), &error);
     106 #endif
     107
     108  /* Check if it is a network stream or a file */
     109  if (hptr) { /* this is a network stream*/
     110    paddr=(struct in_addr *)hptr->h_addr;
     111    bzero(&serv_addr, sizeof(serv_addr));
     112    serv_addr.sin_family=AF_INET;
     113    serv_addr.sin_port=nrtm->port;
     114    memcpy(&serv_addr.sin_addr, paddr, sizeof(struct in_addr));
     115 /*   fprintf(stderr,"Trying %s port %d\n", inet_ntoa(serv_addr.sin_addr), nrtm->port);*/
     116    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))==-1) {
     117      ER_perror(FAC_UD, UD_FS, "cannot connect, errno:%d", errno);
     118      close(sockfd);
     119      return(-1);
     120    }
     121 /*   fprintf(stderr, "Sending Invitation\n"); */
     122
     123    /* Request all available serials (upto LAST), or SBUNCH of them */
     124    line_buff = g_string_sized_new(STR_L);
     125    if(upto_last==1)
     126       g_string_sprintf(line_buff, "-g %s:%d:%ld-LAST\n", source, nrtm->version, nrtm->current_serial+1);
     127    else if(upto_last==-1) /* persistent mirroring */
     128       g_string_sprintf(line_buff, "-k -g %s:%d:%ld-LAST\n", source, nrtm->version, nrtm->current_serial+1);
     129    else
     130       g_string_sprintf(line_buff, "-g %s:%d:%ld-%ld\n", source, nrtm->version, nrtm->current_serial+1, nrtm->current_serial+SBUNCH);
     131    ret=SK_write(sockfd, line_buff->str, line_buff->len, NULL, NULL );
     132    g_string_free(line_buff, TRUE);
     133    if(ret != 1) {
     134            ER_perror(FAC_UD, UD_FS, "cannot write");
     135            close(sockfd);
     136            return(-1);
     137    }
     138    fd=sockfd;
     139    network=1;
     140 /*   fprintf(stderr, "Returning stream pointer\n"); */
     141  }
     142  else { /* this is a file stream*/
     143    network=0;
     144    close(sockfd);
     145 /*   fprintf(stderr, "Trying file ...\n");*/
     146    if((fd=open(nrtm->server, O_RDONLY, 0666))==-1) {
     147       ER_perror(FAC_UD, UD_FS, "cannot open");
     148       return(-1);
     149    }
     150  }
     151  return(fd);
     152 }
     153
     154
     155
     156 /************************************************************
     157 *  void UD_do_nrtm()                                        *
     158 *                                                           *
     159 * Processes NRTM stream                                     *
     160 *                                                           *
     161 * It cycles requesting objects from the NRTM server,        *
     162 * processing them and then sleeping a specified amount of   *
     163 * time.                                                     *
     164 *                                                           *
     165 * It starts by requesting SBUNCH number of serials and does *
     166 * so untill no serials are received (actually a warning     *
     167 * is received saying that the requested range is invalid)   *
     168 * This approach avoids excessive load on the NRTM server    *
     169 *                                                           *
     170 * After that it requests serials using LAST keyward keeping *
     171 * almost in sync with the server                            *
     172 *                                                           *
     173 ************************************************************/
     174
     175 void UD_do_nrtm(void *arg)
         /* [<][>][^][v][top][bottom][index][help] */
     176 {
     177 int source = (int)arg;
     178 UD_stream_t ud_stream;
     179 struct _nrtm *nrtm;
     180 int nrtm_delay;
     181 int do_update=1;
     182 int do_server;
     183 int nrtm_fd;
     184 int num_ok;
     185 int upto_last;
     186 GString *ta_activity;
     187 ca_dbSource_t *source_hdl = ca_get_SourceHandleByPosition(source);
     188 char *db_host, *db_name, *db_user, *db_passwd;
     189 int db_port;
     190 /* get source we are going to mirror */
     191 char *source_name = ca_get_srcname(source_hdl);
     192
     193   { /* set up the lohgging path */
     194    int res;
     195    char *er_ud_def = ca_get_er_ud_def; /* something like 'RIPUPDLOG basename' */
     196    GString *er_def;
     197    char *erret = NULL;
     198
     199    er_def = g_string_sized_new(256);
     200    g_string_sprintf(er_def, "%s %s", er_ud_def, source_name);
     201    fprintf(stderr, "[%s]\n", er_def->str);
     202    if( (res = ER_macro_spec(er_def->str, &erret)) != 0 ) {
     203         fputs(erret, stderr);
     204         die;
     205         /* or some other error handling */
     206    }
     207    UT_free(erret); /* the response is allocated and must be freed */
     208    g_string_free(er_def, TRUE);
     209    UT_free(er_ud_def);
     210   }
     211
     212   /* load the dictionary */
     213   rpsl_load_dictionary(RPSL_DICT_CORE);
     214
     215   nrtm=UT_calloc(1, sizeof(struct _nrtm));
     216   if(nrtm==NULL) {
     217           ER_perror(FAC_UD, UD_MEM, "cannot allocate memory");
     218           die;
     219   }
     220 /* get mode of operation: protected/unprotected (dummy) */
     221   memset(&ud_stream, 0, sizeof(ud_stream));
     222   ud_stream.source_hdl=source_hdl;
     223   ud_stream.ud_mode=ca_get_srcmode(source_hdl);
     224   nrtm_delay=ca_get_srcnrtmdelay(source_hdl);
     225   /* Zero delay means persistent connection */
     226   if (nrtm_delay==0) ud_stream.ud_mode |= B_PERSIST_MIRR;
     227
     228   fprintf(stderr, "Mode of operation:\n");
     229   if(IS_DUMMY_ALLOWED(ud_stream.ud_mode))fprintf(stderr, "* dummy allowed\n");
     230   else fprintf(stderr, "* dummy not allowed\n");
     231
     232   if(IS_UPDATE(ud_stream.ud_mode))fprintf(stderr, "* DBupdate\n");
     233   else if(IS_NRTM_CLNT(ud_stream.ud_mode)) {
     234
     235            if(IS_PERSIST_MIRR(ud_stream.ud_mode))fprintf(stderr, "* NRTM: persistent conection\n");
     236            else fprintf(stderr, "* NRTM\n");
     237         }
     238         else fprintf(stderr, "* STATIC\n");
     239
     240   if(IS_STANDALONE(ud_stream.ud_mode))fprintf(stderr, "* running standalone\n");
     241    else fprintf(stderr, "* running as a server\n");
     242
     243   if(IS_NO_NHR(ud_stream.ud_mode))fprintf(stderr, "* NHR is not maintained\n");
     244    else fprintf(stderr, "* NHR is maintained\n");
     245
     246
     247 /* get mirror server */
     248   nrtm->server=ca_get_srcnrtmhost(source_hdl);
     249
     250
     251 /* get mirror port */
     252   nrtm->port = htons(ca_get_srcnrtmport(source_hdl));
     253   printf("XXX nrtm_port=%d\n", ntohs(nrtm->port));
     254
     255 /* get mirror version */
     256   nrtm->version=ca_get_srcnrtmprotocolvers(source_hdl);
     257
     258
     259 /* get error log facility */
     260 /*   logfilename=ca_get_srcnrtmlog(source_hdl); */
     261
     262    db_host = ca_get_srcdbmachine(source_hdl);
     263    db_port = ca_get_srcdbport(source_hdl);
     264    db_name = ca_get_srcdbname(source_hdl);
     265    db_user = ca_get_srcdbuser(source_hdl);
     266    db_passwd = ca_get_srcdbpassword(source_hdl);
     267
     268 /* Connect to the database */
     269   ER_dbg_va(FAC_UD, ASP_UD_SQL, "%s making SQL connection to %s@%s ...", UD_TAG, db_name, db_host);
     270   ud_stream.db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
     271
     272
     273   if(! ud_stream.db_connection) {
     274     ER_perror(FAC_UD, UD_SQL, "no connection to SQL server");
     275     die;
     276   }
     277
     278   ud_stream.num_skip=0;
     279   ud_stream.load_pass=0;
     280   ud_stream.nrtm=nrtm;
     281
     282   if(IS_PERSIST_MIRR(ud_stream.ud_mode))upto_last=-1; /* the faster the better */
     283   else upto_last=0; /* let's start gradually if the backlog is > SBUNCH (1000) serials*/
     284
     285 /*+++ main cycle +++*/
     286
     287  do {
     288   do_update=CO_get_do_update();
     289   if(do_update) {
     290
     291    /* Check connection to the database and try to reconnect */
     292    if(SQ_ping(ud_stream.db_connection)) {
     293     ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "%s connection to SQL server timed out - reistablishing", UD_TAG);
     294    }
     295
     296   /* get current serial */
     297    nrtm->current_serial=PM_get_current_serial(ud_stream.db_connection);
     298
     299    if(nrtm->current_serial == -1) {
     300       ER_perror(FAC_UD, UD_SQL, "cannot obtain current serial: %ld", nrtm->current_serial);
     301      die;
     302    }
     303
     304    ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "%s connecting to NRTM server [%s:%d] (current serial=%ld)",
     305                                     UD_TAG, nrtm->server, ntohs(nrtm->port), nrtm->current_serial);
     306
     307   /* Get file descriptor of the data stream (RPSL format, use mirror reflector to convert if needed)*/
     308     nrtm_fd=get_NRTM_fd(nrtm, upto_last, source_name);
     309     if (nrtm_fd==-1) {
     310      ER_inf_va(FAC_UD, ASP_UD_OBJ, "%s Cannot open data stream. Trying...", UD_TAG);
     311      SV_sleep(PM_CONNECTION_TIMEOUT);
     312      continue;
     313     }
     314
     315
     316     /* make a record for thread accounting */
     317     TA_add(nrtm_fd, "nrtm_clnt");
     318     ta_activity = g_string_sized_new(STR_M);
     319     g_string_sprintf(ta_activity, "[%s]%ld->",
     320                      source_name, nrtm->current_serial);
     321     TA_setactivity(ta_activity->str);
     322
     323
     324    ud_stream.condat.sock = nrtm_fd;
     325    ud_stream.log.num_ok=0;
     326    ud_stream.log.num_failed=0;
     327
     328
     329    ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s starting processing stream", UD_TAG);
     330
     331 /***************** process stream ****************/
     332
     333       num_ok=UD_process_stream(&ud_stream);
     334
     335 /***************** process stream ****************/
     336
     337    ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s processing stream finished", UD_TAG);
     338
     339   /* close the socket of the NRTM stream */
     340    close(ud_stream.condat.sock);
     341
     342
     343
     344    ER_inf_va(FAC_UD, ASP_UD_OBJ, "%s forwarded to serial:%ld", UD_TAG, (nrtm->current_serial+num_ok));
     345
     346    /* set activity for thread record */
     347    g_string_sprintf(ta_activity, "[%s]->%ld",
     348                     source_name, (nrtm->current_serial+num_ok));
     349    TA_setactivity(ta_activity->str);
     350    g_string_free(ta_activity, TRUE);
     351
     352 /* if we are NOT in persistent mode */
     353    if(!IS_PERSIST_MIRR(ud_stream.ud_mode)) {
     354      /* Now we can process serials in normal way (upto LAST)*/
     355      if(num_ok==0) upto_last=1;
     356      /* get delay */
     357      nrtm_delay=ca_get_srcnrtmdelay(source_hdl);
     358    } else
     359      /* we need to delay the next attempt not to have a birst of requests */
     360      nrtm_delay=TIMEOUT;
     361      /* sleep the delay seconds or untill the shutdown requested */
     362      SV_sleep(nrtm_delay);
     363
     364   } /* if do_updates */
     365   else SV_sleep(TIMEOUT);
     366
     367
     368   TA_delete();
     369
     370  } while((do_server=CO_get_do_server()));  /* main cycle */
     371
     372 /*   fclose(ud_stream.log.logfile);*/
     373    UT_free(source_name);
     374 /* free data associated with nrtm structure */
     375  if(nrtm) {
     376    UT_free(nrtm->server);
     377    UT_free(nrtm);
     378  }
     379
     380  /* That's all. Close connection to the DB */
     381  SQ_close_connection(ud_stream.db_connection);
     382  UT_free(db_host);
     383  UT_free(db_name);
     384  UT_free(db_user);
     385  UT_free(db_passwd);
     386
     387  ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s NRTM client stopped", UD_TAG);
     388 } /* UD_do_nrtm() */
     389
     390 /************************************************************
     391 *  void UD_do_updates()                                     *
     392 *                                                           *
     393 * Processes updates                                         *
     394 *                                                           *
     395 * It cycles accepting connections and processing them       *
     396 * (interactive server). This assures that there is only     *
     397 * one write thread per database/source.                     *
     398 *                                                           *
     399 ************************************************************/
     400
     401 void UD_do_updates(void *arg)
         /* [<][>][^][v][top][bottom][index][help] */
     402 {
     403 int source = (int)arg;
     404 int listening_socket = SV_update_sock[source];
     405 int connected_socket;
     406 UD_stream_t ud_stream;
     407 int do_update=1;
     408 int num_ok;
     409 ca_dbSource_t *source_hdl = ca_get_SourceHandleByPosition(source);
     410 char *db_host, *db_name, *db_user, *db_passwd;
     411 int db_port;
     412 ip_addr_t address;
     413 char *source_name;
     414 struct pollfd pfd[2];
     415
     416    source_name = ca_get_srcname(source_hdl);
     417
     418   { /* set up the lohgging path */
     419    /* get source we are going to update */
     420    int res;
     421    char *er_ud_def = ca_get_er_ud_def; /* something like 'RIPUPDLOG basename' */
     422    GString *er_def;
     423    char *erret = NULL;
     424
     425
     426    er_def = g_string_sized_new(256);
     427    g_string_sprintf(er_def, "%s %s", er_ud_def, source_name);
     428    if( (res = ER_macro_spec(er_def->str, &erret)) != 0 ) {
     429         fputs(erret, stderr);
     430         die;
     431         /* or some other error handling */
     432    }
     433    UT_free(erret); /* the response is allocated and must be freed */
     434    g_string_free(er_def, TRUE);
     435    UT_free(er_ud_def);
     436   }
     437
     438   /* load the dictionary */
     439     rpsl_load_dictionary(RPSL_DICT_CORE);
     440
     441
     442 /* get mode of operation: protected/unprotected (dummy) */
     443   memset(&ud_stream, 0, sizeof(ud_stream));
     444   ud_stream.source_hdl=source_hdl;
     445   ud_stream.ud_mode=ca_get_srcmode(source_hdl);
     446
     447   fprintf(stderr, "Mode of operation:\n");
     448   if(IS_DUMMY_ALLOWED(ud_stream.ud_mode))fprintf(stderr, "* dummy allowed\n");
     449    else fprintf(stderr, "* dummy not allowed\n");
     450   if(IS_UPDATE(ud_stream.ud_mode))fprintf(stderr, "* DBupdate\n");
     451    else fprintf(stderr, "* NRTM\n");
     452   if(IS_STANDALONE(ud_stream.ud_mode))fprintf(stderr, "* running standalone\n");
     453    else fprintf(stderr, "* running as a server\n");
     454
     455
     456 /* get the database */
     457   db_host = ca_get_srcdbmachine(source_hdl);
     458   db_port = ca_get_srcdbport(source_hdl);
     459   db_name = ca_get_srcdbname(source_hdl);
     460   db_user = ca_get_srcdbuser(source_hdl);
     461   db_passwd = ca_get_srcdbpassword(source_hdl);
     462
     463 /* Connect to the database */
     464   ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s making SQL connection to %s@%s ...", UD_TAG, db_name, db_host);
     465   ud_stream.db_connection=SQ_get_connection(db_host, db_port, db_name, db_user, db_passwd);
     466
     467   if(! ud_stream.db_connection) {
     468    ER_perror(FAC_UD, UD_SQL, "no connection to SQL server\n");
     469    die;
     470   }
     471
     472
     473   ud_stream.condat.rd_timeout.tv_sec=STREAM_TIMEOUT;
     474   ud_stream.num_skip=0;
     475   ud_stream.load_pass=0;
     476   ud_stream.nrtm=NULL;
     477
     478   /* set up poll structure */
     479   pfd[0].fd = listening_socket;
     480   pfd[0].events = POLLIN;
     481   pfd[1].fd = SV_shutdown_recv_fd;
     482   pfd[1].events = POLLIN;
     483
     484 /*+++ main cycle +++*/
     485
     486 do { /* be alive while do_server is 1. do_server is turned off by SIGINT */
     487
     488    /* make a record for thread accounting */
     489    TA_add(listening_socket, "update");
     490    TA_setactivity("waiting");
     491
     492    /* check for input */
     493    if (poll(pfd, 2, -1) == -1) {
     494         ER_perror(FAC_SV, 1, "UD_do_updates got error %d on poll; %s",
     495                   errno, strerror(errno));
     496         continue;
     497    }
     498
     499    /* shutdown */
     500    if (pfd[1].revents != 0) break;
     501
     502    /* accept connection */
     503    connected_socket = SK_accept_connection(listening_socket);
     504    if(connected_socket==-1) continue;
     505
     506    /* check if the client is authorised to update */
     507    SK_getpeerip(connected_socket, &address);
     508    if(!AA_can_ripupdate(&address, source_name)){
     509    char *hostaddress;
     510    sk_conn_st condat;
     511    char buff[STR_L];
     512
     513     memset( &condat, 0, sizeof(sk_conn_st));
     514     condat.wr_timeout.tv_sec=STREAM_TIMEOUT;
     515     condat.sock = connected_socket;
     516     SK_getpeerip(connected_socket, &(condat.rIP));
     517     memcpy( &(condat.eIP), &(condat.rIP), sizeof(ip_addr_t));
     518     hostaddress = SK_getpeername(connected_socket);
     519     condat.ip = hostaddress;
     520
     521     ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "[%s] --  Not authorized to update the source %s", hostaddress, source_name);
     522     sprintf(buff, "\n%%ERROR:406: not authorized to update the database\n\n\n");
     523     SK_cd_puts(&condat, buff);
     524     SK_cd_close(&(condat));
     525
     526     UT_free(hostaddress);
     527     /* start the next loop */
     528     continue;
     529    }
     530
     531    /* make a record for thread accounting */
     532    TA_delete(); /* Delete 'waiting' record */
     533    TA_add(connected_socket, "update");
     534
     535
     536    ud_stream.condat.sock = connected_socket;
     537    ud_stream.condat.rtc = 0;
     538
     539
     540    ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s Connection accepted...", UD_TAG);
     541
     542    ud_stream.log.num_ok=0;
     543    ud_stream.log.num_failed=0;
     544
     545
     546    while((do_update=CO_get_do_update())!=1) {
     547            TA_setactivity("suspended");
     548            /* if shutdown was requested - break */
     549            if(SV_sleep(3*TIME_SLICE)) break;
     550    }
     551
     552    if(do_update) {
     553      /* Check connection to the database and try to reconnect*/
     554      if(SQ_ping(ud_stream.db_connection)) {
     555        ER_perror(FAC_UD, UD_SQL, "%s", SQ_error(ud_stream.db_connection));
     556        die;
     557      }
     558
     559      ER_dbg_va(FAC_UD, ASP_UD_UPDLOG, "%s starting processing object", UD_TAG);
     560
     561      /***************** process stream ****************/
     562
     563       num_ok=UD_process_stream(&ud_stream);
     564
     565      /***************** process stream ****************/
     566
     567       ER_dbg_va(FAC_UD, ASP_UD_OBJ, "%s processing object finished", UD_TAG);
     568
     569      /* close the socket of the NRTM stream */
     570      close(ud_stream.condat.sock);
     571
     572    }  /* if do_update*/
     573
     574
     575    TA_delete();
     576
     577 } while (CO_get_do_server());  /* main cycle */
     578
     579 /*   fclose(ud_stream.log.logfile); */
     580  /* That's all. Close connection to the DB */
     581  SQ_close_connection(ud_stream.db_connection);
     582  UT_free(db_host);
     583  UT_free(db_name);
     584  UT_free(db_user);
     585  UT_free(db_passwd);
     586  UT_free(source_name);
     587
     588
     589  ER_inf_va(FAC_UD, ASP_UD_UPDLOG, "%s update server stopped", UD_TAG);
     590 } /* UD_do_update() */
     591
     592
     593
     594

/* [<][>][^][v][top][bottom][index][help] */