2 * Copyright (c) 2000, Red Hat, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
16 /* The purpose of this file is to intall all the packages selected in
17 the install list (in ini.h). Note that we use a separate thread to
18 maintain the progress dialog, so we avoid the complexity of
19 handling two tasks in one thread. We also create or update all the
20 files in /etc/setup and create the mount points. */
28 #include <sys/types.h>
53 static HWND ins_dialog = 0;
54 static HWND ins_action = 0;
55 static HWND ins_pkgname = 0;
56 static HWND ins_filename = 0;
57 static HWND ins_pprogress = 0;
58 static HWND ins_iprogress = 0;
59 static HWND ins_diskfull = 0;
60 static HANDLE init_event;
62 static int total_bytes = 0;
63 static int total_bytes_sofar = 0;
64 static int package_bytes = 0;
67 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
78 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
84 ins_action = GetDlgItem (h, IDC_INS_ACTION);
85 ins_pkgname = GetDlgItem (h, IDC_INS_PKG);
86 ins_filename = GetDlgItem (h, IDC_INS_FILE);
87 ins_pprogress = GetDlgItem (h, IDC_INS_PPROGRESS);
88 ins_iprogress = GetDlgItem (h, IDC_INS_IPROGRESS);
89 ins_diskfull = GetDlgItem (h, IDC_INS_DISKFULL);
90 SetEvent (init_event);
93 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
102 HWND new_dialog = CreateDialog (hinstance, MAKEINTRESOURCE (IDD_INSTATUS),
105 fatal ("create dialog");
106 ShowWindow (new_dialog, SW_SHOWNORMAL);
107 UpdateWindow (new_dialog);
108 while (GetMessage (&m, 0, 0, 0) > 0) {
109 TranslateMessage (&m);
110 DispatchMessage (&m);
122 init_event = CreateEvent (0, 0, 0, 0);
123 thread = CreateThread (0, 0, dialog, 0, 0, &tid);
124 WaitForSingleObject (init_event, 10000);
125 CloseHandle (init_event);
126 SendMessage (ins_pprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
127 SendMessage (ins_iprogress, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
128 SendMessage (ins_diskfull, PBM_SETRANGE, 0, MAKELPARAM (0, 100));
131 SetWindowText (ins_pkgname, "");
132 SetWindowText (ins_filename, "");
133 SendMessage (ins_pprogress, PBM_SETPOS, (WPARAM) 0, 0);
134 SendMessage (ins_iprogress, PBM_SETPOS, (WPARAM) 0, 0);
135 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) 0, 0);
136 ShowWindow (ins_dialog, SW_SHOWNORMAL);
137 SetForegroundWindow (ins_dialog);
145 if (package_bytes > 100)
147 perc = bytes / (package_bytes / 100);
148 SendMessage (ins_pprogress, PBM_SETPOS, (WPARAM) perc, 0);
151 if (total_bytes > 100)
153 perc = (total_bytes_sofar + bytes) / (total_bytes / 100);
154 SendMessage (ins_iprogress, PBM_SETPOS, (WPARAM) perc, 0);
159 badrename (char *o, char *n)
161 char *err = strerror (errno);
163 err = "(unknown error)";
164 note (IDS_ERR_RENAME, o, n, err);
167 static char *standard_dirs[] = {
172 hash::add_subdirs (char *path)
175 for (nonp = path; *nonp == '\\' || *nonp == '/'; nonp++);
176 for (pp = path + strlen(path) - 1; pp>nonp; pp--)
177 if (*pp == '/' || *pp == '\\')
182 for (i=0; standard_dirs[i]; i++)
183 if (strcmp (standard_dirs[i]+1, path) == 0)
195 map_filename (char *fn, int type)
198 while (*fn == '/' || *fn == '\\')
200 if (type == TY_GENERIC)
201 dest_file = concat (root_dir, XEMACS_PACKAGE_DIR, fn, 0);
202 else // TY_CYGWIN | TY_NATIVE
203 dest_file = concat (root_dir, "/", fn, 0);
210 if (_access (file, 0) == 0)
216 static int num_installs, num_uninstalls;
219 uninstall_one (char *name, int action, int type)
222 char line[_MAX_PATH];
223 char* fname = (type == TY_GENERIC ?
224 concat (root_dir, XEMACS_PACKAGE_DIR, "pkginfo/MANIFEST.",
226 concat (root_dir, XEMACS_SETUP_DIR, "MANIFEST.", name, 0));
228 FILE* lst = fopen (fname, "rb");
232 SetWindowText (ins_pkgname, name);
233 SetWindowText (ins_action, "Uninstalling...");
234 // remove shortcuts and registry entries
235 if (type != TY_GENERIC)
236 remove_xemacs_setup();
238 if (action == ACTION_UPGRADE)
239 log (0, "Uninstalling old %s", name);
241 log (0, "Uninstalling %s", name);
243 while (fgets (line, sizeof (line), lst))
245 if (line[strlen(line)-1] == '\n')
246 line[strlen(line)-1] = 0;
248 dirs.add_subdirs (line);
250 char *d = map_filename (line, type);
251 DWORD dw = GetFileAttributes (d);
252 if (dw != 0xffffffff && !(dw & FILE_ATTRIBUTE_DIRECTORY))
254 log (LOG_BABBLE, "unlink %s", d);
262 dirs.reverse_sort ();
264 while ((subdir = dirs.enumerate (subdir)) != 0)
266 char *d = map_filename (subdir, type);
267 if (RemoveDirectory (d))
268 log (LOG_BABBLE, "rmdir %s", d);
276 install_one (char *name, char *file, int file_size, int action, int type)
279 char *local = file, *cp, *fn, *base;
282 for (cp=local; *cp; cp++)
283 if (*cp == '/' || *cp == '\\' || *cp == ':')
286 SetWindowText (ins_pkgname, base);
288 if (!exists (local) && exists (base))
292 note (IDS_ERR_OPEN_READ, local, "No such file");
296 char* fname = (type == TY_GENERIC ?
297 concat (root_dir, XEMACS_PACKAGE_DIR, "pkginfo/MANIFEST.",
299 concat (root_dir, XEMACS_SETUP_DIR, "MANIFEST.", name, 0));
301 FILE* lst = fopen (fname, "wb");
303 package_bytes = file_size;
308 SetWindowText (ins_action, "Installing...");
311 SetWindowText (ins_action, "Upgrading...");
315 log (0, "Installing %s", local);
317 while ((fn = tar_next_file ()))
319 char *dest_file, *disp_file;
323 fprintf (lst, "%s\n", fn);
325 dest_file = map_filename (fn, type);
327 // The installer uses a variable width font. Assume roughly 32 chars
328 // will fit and munge the file accordingly.
329 #define MAX_DISP_SIZE 50
330 disp_file = strdup(dest_file);
331 if ((len = strlen(dest_file)) > MAX_DISP_SIZE) {
332 disp_file += (len - MAX_DISP_SIZE);
338 SetWindowText (ins_filename, disp_file);
340 log (LOG_BABBLE, "Installing file %s", dest_file);
341 if (tar_read_file (dest_file) != 0)
343 log (0, "Unable to install file %s", dest_file);
347 progress (tar_ftell ());
352 total_bytes_sofar += file_size;
355 int df = diskfull (root_dir);
356 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
365 do_install (HINSTANCE h)
370 num_installs = 0, num_uninstalls = 0;
372 next_dialog = IDD_DESKTOP;
374 mkdir_p (1, root_dir);
376 for (i=0; standard_dirs[i]; i++)
378 char *p = concat (root_dir, standard_dirs[i], 0);
383 dismiss_url_status_dialog ();
388 total_bytes_sofar = 0;
390 int df = diskfull (root_dir);
391 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
395 total_bytes += pi.install_size;
398 for (i=0; i<npackages; i++)
400 if (package[i].action == ACTION_UNINSTALL
401 || (package[i].action == ACTION_UPGRADE && pi.install))
403 uninstall_one (package[i].name, package[i].action,
405 uninstall_one (concat (package[i].name, "-src", 0), package[i].action,
409 if ((package[i].action == ACTION_NEW
410 || package[i].action == ACTION_UPGRADE)
413 int e = install_one (package[i].name, pi.install, pi.install_size, package[i].action,
415 if (package[i].srcaction == SRCACTION_YES && pi.source)
416 e += install_one (concat (package[i].name, "-src", 0), pi.source, pi.source_size,
417 package[i].action, package[i].type);
420 package[i].action = ACTION_ERROR;
424 } // end of big package loop
426 ShowWindow (ins_dialog, SW_HIDE);
428 char *odbn = concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0);
429 char *ndbn = concat (root_dir, XEMACS_SETUP_DIR, "installed.db.new", 0);
430 char *sdbn = concat (root_dir, XEMACS_SETUP_DIR, "installed.db.old", 0);
434 FILE *odb = fopen (odbn, "rt");
435 FILE *ndb = fopen (ndbn, "wb");
439 char *err = strerror (errno);
441 err = "(unknown error)";
442 fatal (IDS_ERR_OPEN_WRITE, ndb, err);
447 char line[1000], pkg[1000];
449 while (fgets (line, 1000, odb))
452 sscanf (line, "%s", pkg);
453 for (i=0; i<npackages; i++)
455 if (strcmp (pkg, package[i].name) == 0)
456 switch (package[i].action)
460 case ACTION_UNINSTALL:
473 if (package[i].srcaction == SRCACTION_YES)
474 fprintf (ndb, "%s %s %d %s %d\n", package[i].name,
475 pi.install, pi.install_size,
476 pi.source, pi.source_size);
478 fprintf (ndb, "%s %s %d\n", package[i].name,
479 pi.install, pi.install_size);
487 if (odb && rename (odbn, sdbn))
488 badrename (odbn, sdbn);
491 if (rename (ndbn, odbn))
492 badrename (ndbn, odbn);
494 if (num_installs == 0 && num_uninstalls == 0)
496 exit_msg = IDS_NOTHING_INSTALLED;
499 if (num_installs == 0)
501 exit_msg = IDS_UNINSTALL_COMPLETE;
506 exit_msg = IDS_INSTALL_INCOMPLETE;
508 exit_msg = IDS_INSTALL_COMPLETE;