SILC Map distribution added.
[silc.git] / apps / silcmap / silcmap_client.c
index 03cc47e6c55c913770c2c9dcc488ab6f61fa2f5a..651bd5647b827a74001f4272cf487d6d378af43c 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2003 Pekka Riikonen
+  Copyright (C) 2003 - 2004 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -39,119 +39,160 @@ void silc_map_process_data(SilcMap map, SilcMapConnection mapconn)
   SilcMapCommand cmd;
   SilcMap ret_map;
   SilcInt16 r, g, b, lr, lg, lb;
+  int i;
 
   map->conn_num++;
+
   SILC_LOG_DEBUG(("Processing the data from server (%d/%d)",
                  map->conn_num, map->conns_num));
 
-  /* Change colors according to server status */
-  silc_map_parse_color(mapconn->up_color, &r, &g, &b);
-  silc_map_parse_color(mapconn->up_text_color, &lr, &lg, &lb);
-  if (mapconn->down) {
-    silc_map_parse_color(mapconn->down_color, &r, &g, &b);
-    silc_map_parse_color(mapconn->down_text_color, &lr, &lg, &lb);
+  if (map->conn_num != map->conns_num)
+    return;
+
+  /* Load the map image to be processed */
+  silc_free(map->bitmap);
+  if (!map->loadmap.loadmap || !map->loadmap.filename) {
+    silc_schedule_task_add(map->client->schedule, 0,
+                          silc_map_process_done, map, 0, 1,
+                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+    return;
   }
 
-  /* Execute the map commands */
-  silc_dlist_start(mapconn->commands);
-  while ((cmd = silc_dlist_get(mapconn->commands)) != SILC_LIST_END) {
-    if (cmd->cut) {
-      if (silc_map_cut(map, cmd->x, cmd->y, cmd->width,
-                      cmd->height, &ret_map)) {
-       silc_map_write_ppm(ret_map, cmd->filename);
-       silc_map_free(ret_map);
-      }
-      continue;
-    }
+  if (!silc_map_load_ppm(map, map->loadmap.filename)) {
+    silc_schedule_task_add(map->client->schedule, 0,
+                          silc_map_process_done, map, 0, 1,
+                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
+    return;
+  }
 
-    if (cmd->draw_line) {
-      if (cmd->color_set) {
-       r = cmd->r;
-       g = cmd->g;
-       b = cmd->b;
-      }
-      silc_map_draw_line(map, cmd->width, cmd->x, cmd->y, cmd->x2, cmd->y2,
-                        r, g, b);
-      continue;
+  /* Now process all received data one by one */
+  silc_dlist_start(map->conns);
+  while ((mapconn = silc_dlist_get(map->conns)) != SILC_LIST_END) {
+
+    /* Change colors according to server status */
+    silc_map_parse_color(mapconn->up_color, &r, &g, &b);
+    silc_map_parse_color(mapconn->up_text_color, &lr, &lg, &lb);
+    if (mapconn->down) {
+      silc_map_parse_color(mapconn->down_color, &r, &g, &b);
+      silc_map_parse_color(mapconn->down_text_color, &lr, &lg, &lb);
     }
 
-    if (cmd->draw_text) {
-      if (cmd->color_set) {
-       lr = cmd->r;
-       lg = cmd->g;
-       lb = cmd->b;
+    /* Execute the map commands */
+    silc_dlist_start(mapconn->commands);
+    while ((cmd = silc_dlist_get(mapconn->commands)) != SILC_LIST_END) {
+      if (cmd->alon && cmd->alat) {
+       cmd->x = silc_map_lon2x(map, cmd->alon);
+       cmd->y = silc_map_lat2y(map, cmd->alat);
+       if (cmd->blon && cmd->blat) {
+         cmd->x2 = silc_map_lon2x(map, cmd->blon);
+         cmd->y2 = silc_map_lat2y(map, cmd->blat);
+       }
       }
-      silc_map_draw_text(map, cmd->text, cmd->x, cmd->y, lr, lg, lb);
 
-      continue;
-    }
+      if (cmd->cut) {
+       if (silc_map_cut(map, cmd->x, cmd->y, cmd->width,
+                        cmd->height, &ret_map)) {
+         silc_map_write_ppm(ret_map, cmd->filename);
+         silc_map_free(ret_map);
+       }
+       continue;
+      }
 
-    if (cmd->draw_circle) {
-      if (cmd->color_set) {
-       r = cmd->r;
-       g = cmd->g;
-       b = cmd->b;
+      if (cmd->draw_line) {
+       if (cmd->color_set) {
+         r = cmd->r;
+         g = cmd->g;
+         b = cmd->b;
+       }
+       silc_map_draw_line(map, cmd->width, cmd->x, cmd->y, cmd->x2, cmd->y2,
+                          r, g, b);
+       continue;
       }
-      if (cmd->lcolor_set) {
-       lr = cmd->lr;
-       lg = cmd->lg;
-       lb = cmd->lb;
+
+      if (cmd->draw_text) {
+       if (cmd->color_set) {
+         lr = cmd->r;
+         lg = cmd->g;
+         lb = cmd->b;
+       }
+       silc_map_draw_text(map, cmd->text, cmd->x, cmd->y, lr, lg, lb);
+       continue;
       }
-      silc_map_draw_circle(map, cmd->x, cmd->y, r, g, b,
-                          cmd->text, cmd->lposx, cmd->lposy, lr, lg, lb);
-      continue;
-    }
 
-    if (cmd->draw_rectangle) {
-      if (cmd->color_set) {
-       r = cmd->r;
-       g = cmd->g;
-       b = cmd->b;
+      if (cmd->draw_circle) {
+       if (cmd->color_set) {
+         r = cmd->r;
+         g = cmd->g;
+         b = cmd->b;
+       }
+       if (cmd->lcolor_set) {
+         lr = cmd->lr;
+         lg = cmd->lg;
+         lb = cmd->lb;
+       }
+       silc_map_draw_circle(map, cmd->x, cmd->y, r, g, b,
+                            cmd->text, cmd->lposx, cmd->lposy, lr, lg, lb);
+       continue;
       }
-      if (cmd->lcolor_set) {
-       lr = cmd->lr;
-       lg = cmd->lg;
-       lb = cmd->lb;
+
+      if (cmd->draw_rectangle) {
+       if (cmd->color_set) {
+         r = cmd->r;
+         g = cmd->g;
+         b = cmd->b;
+       }
+       if (cmd->lcolor_set) {
+         lr = cmd->lr;
+         lg = cmd->lg;
+         lb = cmd->lb;
+       }
+       silc_map_draw_rectangle(map, cmd->x, cmd->y, r, g, b,
+                               cmd->text, cmd->lposx, cmd->lposy, lr, lg, lb);
+       continue;
       }
-      silc_map_draw_rectangle(map, cmd->x, cmd->y, r, g, b,
-                             cmd->text, cmd->lposx, cmd->lposy, lr, lg, lb);
-      continue;
     }
 
+    /* Write the html data file */
+    if (map->writehtml.writehtml)
+      silc_map_writehtml(map, mapconn);
+
+    /* Write uptime reliability data */
+    if (map->writerel.writerel)
+      silc_map_writerel(map, mapconn);
   }
 
-  /* Write the html data file */
-  if (map->writehtml.writehtml)
-    silc_map_writehtml(map, mapconn);
-
-  /* If this was last connection, we are done and ready to quit. */
-  if (map->conn_num == map->conns_num) {
-    SILC_LOG_DEBUG(("All connections processed"));
-
-    /* Produce output */
-    if (map->writemap.writemap)
-      silc_map_write_ppm(map, map->writemap.filename);
-    if (map->cut.cut) {
-      if (silc_map_cut(map, map->cut.x, map->cut.y, map->cut.width,
-                      map->cut.height, &ret_map)) {
-       silc_map_write_ppm(ret_map, map->cut.filename);
-       silc_map_free(ret_map);
-      }
+  SILC_LOG_DEBUG(("All connections processed"));
+
+  /* Produce output */
+  if (map->writemap.writemap)
+    silc_map_write_ppm(map, map->writemap.filename);
+  for (i = 0; i < map->cut_count; i++) {
+    if (map->cut[i].alon && map->cut[i].alat) {
+      map->cut[i].x = silc_map_lon2x(map, map->cut[i].alon);
+      map->cut[i].y = silc_map_lat2y(map, map->cut[i].alat);
+    }
+    if (silc_map_cut(map, map->cut[i].x, map->cut[i].y, map->cut[i].width,
+                    map->cut[i].height, &ret_map)) {
+      silc_map_write_ppm(ret_map, map->cut[i].filename);
+      silc_map_free(ret_map);
     }
+  }
 
-    /* Write the HTML index file */
-    if (map->writehtml.writehtml)
-      silc_map_writehtml_index(map);
+  /* Write the HTML index file */
+  if (map->writehtml.writehtml)
+    silc_map_writehtml_index(map);
 
-    /* Write the HTML map file */
-    if (map->writemaphtml.writemaphtml)
-      silc_map_writemaphtml(map);
+  /* Write the HTML map file(s) */
+  silc_map_writemaphtml(map);
 
-    /* Schedule to stop */
-    silc_schedule_task_add(map->client->schedule, 0,
-                          silc_map_process_done, map, 0, 1,
-                          SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
-  }
+  /* Write uptime reliability graph */
+  if (map->writerel.writerel)
+    silc_map_writerelhtml(map);
+
+  /* Schedule to stop */
+  silc_schedule_task_add(map->client->schedule, 0,
+                        silc_map_process_done, map, 0, 1,
+                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 }
 
 /* Timeout callback to detect if server is down. */
@@ -162,9 +203,33 @@ SILC_TASK_CALLBACK(silc_map_connect_timeout)
 
   SILC_LOG_DEBUG(("Connection timeout"));
 
+  silc_schedule_task_del_by_context(mapconn->map->client->schedule, mapconn);
+
+  /* The server is down. */
+  mapconn->down = TRUE;
+
+  /* Continue to produce the data and the map. */
+  silc_map_process_data(mapconn->map, mapconn);
+}
+
+/* Timeout callback to detect if server is down. */
+
+SILC_TASK_CALLBACK(silc_map_data_timeout)
+{
+  SilcMapConnection mapconn = context;
+
+  SILC_LOG_DEBUG(("data timeout"));
+
+  silc_schedule_task_del_by_context(mapconn->map->client->schedule, mapconn);
+
   /* The server is down. */
   mapconn->down = TRUE;
 
+  /* Close connection, we didn't get any data. */
+  SILC_LOG_DEBUG(("Closing connection to %s:%d", mapconn->conn->remote_host,
+                 mapconn->conn->remote_port));
+  silc_client_close_connection(mapconn->conn->client, mapconn->conn);
+
   /* Continue to produce the data and the map. */
   silc_map_process_data(mapconn->map, mapconn);
 }
@@ -240,7 +305,8 @@ static void
 silc_channel_message(SilcClient client, SilcClientConnection conn,
                     SilcClientEntry sender, SilcChannelEntry channel,
                     SilcMessagePayload payload,
-                    SilcMessageFlags flags, const unsigned char *message,
+                    SilcChannelPrivateKey key, SilcMessageFlags flags,
+                    const unsigned char *message,
                     SilcUInt32 message_len)
 {
 
@@ -342,7 +408,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcUInt32 stats_len = va_arg(va, SilcUInt32);
       SilcBufferStruct buf;
 
-      SILC_LOG_DEBUG(("STATS command reply"));
+      SILC_LOG_DEBUG(("STATS command reply from %s", conn->sock->hostname));
 
       /* Get statistics structure */
       silc_buffer_set(&buf, stats, stats_len);
@@ -380,6 +446,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
     break;
 
   default:
+    SILC_LOG_DEBUG(("Unsupported command reply"));
     break;
   };
 
@@ -390,6 +457,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
   if (!mapconn->stats_received)
     return;
 
+  silc_schedule_task_del_by_context(client->schedule, mapconn);
+
   /* All data is gathered, time to disconnect from the server. */
   silc_schedule_task_add(client->schedule, 0,
                         silc_map_connect_close, mapconn, 0, 1,
@@ -412,8 +481,9 @@ silc_connected(SilcClient client, SilcClientConnection conn,
 
   silc_schedule_task_del_by_context(client->schedule, mapconn);
 
-  if (status == SILC_CLIENT_CONN_ERROR) {
-    fprintf(stderr, "Could not connect to server\n");
+  if (status != SILC_CLIENT_CONN_SUCCESS) {
+    fprintf(stderr, "Could not connect to server %s\n",
+                    conn->remote_host ? conn->remote_host : "");
     silc_client_close_connection(client, conn);
 
     /* Mark that this server is down. */
@@ -425,6 +495,7 @@ silc_connected(SilcClient client, SilcClientConnection conn,
 
   if (mapconn->down) {
     /* Already timeouted */
+    SILC_LOG_DEBUG(("Connection already timedout"));
     silc_client_close_connection(client, conn);
     return;
   }
@@ -448,6 +519,12 @@ silc_connected(SilcClient client, SilcClientConnection conn,
     silc_strncat(motd, sizeof(motd), hostname, strlen(hostname));
     silc_client_command_call(client, conn, motd);
   }
+
+  /* Set data timeout to detect if the server is down. */
+  silc_schedule_task_add(map->client->schedule, 0,
+                        silc_map_data_timeout, mapconn,
+                        mapconn->connect_timeout, 0,
+                        SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 }