Initial revision
[chise/xemacs-chise.git.1] / netinstall / geturl.cc
diff --git a/netinstall/geturl.cc b/netinstall/geturl.cc
new file mode 100644 (file)
index 0000000..864319f
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2000, Red Hat, Inc.
+ *
+ *     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
+ *     the Free Software Foundation; either version 2 of the License, or
+ *     (at your option) any later version.
+ *
+ *     A copy of the GNU General Public License can be found at
+ *     http://www.gnu.org/
+ *
+ * Written by DJ Delorie <dj@cygnus.com>
+ *
+ */
+
+/* The purpose of this file is to act as a pretty interface to
+   netio.cc.  We add a progress dialog and some convenience functions
+   (like collect to string or file */
+
+#include "win32.h"
+#include "commctrl.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "dialog.h"
+#include "geturl.h"
+#include "resource.h"
+#include "netio.h"
+#include "msg.h"
+#include "log.h"
+
+static int is_showing = 0;
+static HWND gw_dialog = 0;
+static HWND gw_url = 0;
+static HWND gw_rate = 0;
+static HWND gw_progress = 0;
+static HANDLE init_event;
+static int max_bytes = 0;
+
+static BOOL
+dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
+{
+  switch (id)
+    {
+    case IDCANCEL:
+      exit_setup (0);
+    }
+  return FALSE;
+}
+
+static BOOL CALLBACK
+dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  switch (message)
+    {
+    case WM_INITDIALOG:
+      gw_dialog = h;
+      gw_url = GetDlgItem (h, IDC_DLS_URL);
+      gw_rate = GetDlgItem (h, IDC_DLS_RATE);
+      gw_progress = GetDlgItem (h, IDC_DLS_PROGRESS);
+      SetEvent (init_event);
+      return FALSE;
+    case WM_COMMAND:
+      return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
+    }
+  return FALSE;
+}
+
+static DWORD WINAPI
+dialog (void *)
+{
+  MSG m;
+  HWND gw_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_DLSTATUS),
+                                  0, dialog_proc);
+  ShowWindow (gw_dialog, SW_SHOWNORMAL);
+  UpdateWindow (gw_dialog);
+  while (GetMessage (&m, 0, 0, 0) > 0) {
+    TranslateMessage (&m);
+    DispatchMessage (&m);
+  }
+  return FALSE;
+}
+
+static DWORD start_tics;
+
+static void
+init_dialog (char *url, int length)
+{
+  if (gw_dialog == 0)
+    {
+      DWORD tid;
+      HANDLE thread;
+      init_event = CreateEvent (0, 0, 0, 0);
+      thread = CreateThread (0, 0, dialog, 0, 0, &tid);
+      WaitForSingleObject (init_event, 1000);
+      CloseHandle (init_event);
+      SendMessage (gw_progress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
+      is_showing = 0;
+    }
+  char *sl=url, *cp;
+  for (cp=url; *cp; cp++)
+    if (*cp == '/' || *cp == '\\' || *cp == ':')
+      sl = cp+1;
+  max_bytes = length;
+  SetWindowText (gw_url, sl);
+  SetWindowText (gw_rate, "Connecting...");
+  SendMessage (gw_progress, PBM_SETPOS, (WPARAM) 0, 0);
+  ShowWindow (gw_progress, (length > 0) ? SW_SHOW : SW_HIDE);
+  ShowWindow (gw_dialog, SW_SHOWNORMAL);
+  if (!is_showing)
+    {
+      SetForegroundWindow (gw_dialog);
+      is_showing = 1;
+    }
+  start_tics = GetTickCount ();
+}
+
+
+static void
+progress (int bytes)
+{
+  static char buf[100];
+  int kbps;
+  static DWORD last_tics = 0;
+  DWORD tics = GetTickCount ();
+  if (tics == start_tics) // to prevent division by zero
+    return;
+  if (tics < last_tics + 200) // to prevent flickering updates
+    return;
+  last_tics = tics;
+
+  kbps = bytes / (tics - start_tics);
+  ShowWindow (gw_progress, (max_bytes > 0) ? SW_SHOW : SW_HIDE);
+  if (max_bytes > 100)
+    {
+      int perc = bytes / (max_bytes / 100);
+      SendMessage (gw_progress, PBM_SETPOS, (WPARAM) perc, 0);
+      sprintf (buf, "%3d %%  (%dk/%dk)  %d kb/s\n",
+              perc, bytes/1000, max_bytes/1000, kbps);
+    }
+  else
+    sprintf (buf, "%d  %d kb/s\n", bytes, kbps);
+
+  SetWindowText (gw_rate, buf);
+}
+
+struct GUBuf {
+  GUBuf *next;
+  int count;
+  char buf[2000];
+};
+
+char *
+get_url_to_string (char *_url)
+{
+  log (LOG_BABBLE, "get_url_to_string %s", _url);
+  init_dialog (_url, 0);
+  NetIO *n = NetIO::open (_url);
+  if (!n || !n->ok ())
+    {
+      delete n;
+      log (LOG_BABBLE, "get_url_to_string failed!");
+      return 0;
+    }
+
+  if (n->file_size)
+    max_bytes = n->file_size;
+
+  GUBuf *bufs = 0;
+  GUBuf **nextp = &bufs;
+  int total_bytes = 1; /* for the NUL */
+  progress (0);
+  while (1)
+    {
+      GUBuf *b = new GUBuf;
+      *nextp = b;
+      b->next = 0;
+      nextp = &(b->next);
+
+      b->count = n->read (b->buf, sizeof (b->buf));
+      if (b->count <= 0)
+       break;
+      total_bytes += b->count;
+      progress (total_bytes);
+    }
+
+  char *rv = (char *) malloc (total_bytes);
+  char *rvp = rv;
+  while (bufs && bufs->count > 0)
+    {
+      GUBuf *tmp = bufs->next;
+      memcpy (rvp, bufs->buf, bufs->count);
+      rvp += bufs->count;
+      delete bufs;
+      bufs = tmp;
+    }
+  *rvp = 0;
+  return rv;
+}
+
+int
+get_url_to_file (char *_url, char *_filename, int expected_length)
+{
+  log (LOG_BABBLE, "get_url_to_file %s %s", _url, _filename);
+  init_dialog (_url, expected_length);
+
+  remove (_filename); /* but ignore errors */
+
+  NetIO *n = NetIO::open (_url);
+  if (!n || !n->ok ())
+    {
+      delete n;
+      log (LOG_BABBLE, "get_url_to_file failed!");
+      return 1;
+    }
+
+  FILE *f = fopen (_filename, "wb");
+  if (!f)
+    {
+      char *err = strerror (errno);
+      if (!err)
+       err = "(unknown error)";
+      fatal (IDS_ERR_OPEN_WRITE, _filename, err);
+    }
+
+  if (n->file_size)
+    max_bytes = n->file_size;
+
+  int total_bytes = 0;
+  progress (0);
+  while (1)
+    {
+      char buf[8192];
+      int count;
+      count = n->read (buf, sizeof (buf));
+      if (count <= 0)
+       break;
+      fwrite (buf, 1, count, f);
+      total_bytes += count;
+      progress (total_bytes);
+    }
+
+  fclose (f);
+
+  return 0;
+}
+
+void
+dismiss_url_status_dialog ()
+{
+  ShowWindow (gw_dialog, SW_HIDE);
+  is_showing = 0;
+}