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 if (action == ACTION_UPGRADE)
235 log (0, "Uninstalling old %s", name);
237 log (0, "Uninstalling %s", name);
239 while (fgets (line, sizeof (line), lst))
241 if (line[strlen(line)-1] == '\n')
242 line[strlen(line)-1] = 0;
244 dirs.add_subdirs (line);
246 char *d = map_filename (line, type);
247 DWORD dw = GetFileAttributes (d);
248 if (dw != 0xffffffff && !(dw & FILE_ATTRIBUTE_DIRECTORY))
250 log (LOG_BABBLE, "unlink %s", d);
258 dirs.reverse_sort ();
260 while ((subdir = dirs.enumerate (subdir)) != 0)
262 char *d = map_filename (subdir, type);
263 if (RemoveDirectory (d))
264 log (LOG_BABBLE, "rmdir %s", d);
272 install_one (char *name, char *file, int file_size, int action, int type)
275 char *local = file, *cp, *fn, *base;
278 for (cp=local; *cp; cp++)
279 if (*cp == '/' || *cp == '\\' || *cp == ':')
281 SetWindowText (ins_pkgname, base);
283 if (!exists (local) && exists (base))
287 note (IDS_ERR_OPEN_READ, local, "No such file");
291 char* fname = (type == TY_GENERIC ?
292 concat (root_dir, XEMACS_PACKAGE_DIR, "pkginfo/MANIFEST.",
294 concat (root_dir, XEMACS_SETUP_DIR, "MANIFEST.", name, 0));
296 FILE* lst = fopen (fname, "wb");
298 package_bytes = file_size;
303 SetWindowText (ins_action, "Installing...");
306 SetWindowText (ins_action, "Upgrading...");
310 log (0, "Installing %s", local);
312 while ((fn = tar_next_file ()))
317 fprintf (lst, "%s\n", fn);
319 dest_file = map_filename (fn, type);
321 SetWindowText (ins_filename, dest_file);
322 log (LOG_BABBLE, "Installing file %s", dest_file);
323 if (tar_read_file (dest_file) != 0)
325 log (0, "Unable to install file %s", dest_file);
329 progress (tar_ftell ());
334 total_bytes_sofar += file_size;
337 int df = diskfull (root_dir);
338 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
347 do_install (HINSTANCE h)
352 num_installs = 0, num_uninstalls = 0;
354 next_dialog = IDD_DESKTOP;
356 mkdir_p (1, root_dir);
358 for (i=0; standard_dirs[i]; i++)
360 char *p = concat (root_dir, standard_dirs[i], 0);
365 dismiss_url_status_dialog ();
370 total_bytes_sofar = 0;
372 int df = diskfull (root_dir);
373 SendMessage (ins_diskfull, PBM_SETPOS, (WPARAM) df, 0);
377 total_bytes += pi.install_size;
380 for (i=0; i<npackages; i++)
382 if (package[i].action == ACTION_UNINSTALL
383 || (package[i].action == ACTION_UPGRADE && pi.install))
385 uninstall_one (package[i].name, package[i].action,
387 uninstall_one (concat (package[i].name, "-src", 0), package[i].action,
391 if ((package[i].action == ACTION_NEW
392 || package[i].action == ACTION_UPGRADE)
395 int e = install_one (package[i].name, pi.install, pi.install_size, package[i].action,
397 if (package[i].srcaction == SRCACTION_YES && pi.source)
398 e += install_one (concat (package[i].name, "-src", 0), pi.source, pi.source_size,
399 package[i].action, package[i].type);
402 package[i].action = ACTION_ERROR;
406 } // end of big package loop
408 ShowWindow (ins_dialog, SW_HIDE);
410 char *odbn = concat (root_dir, XEMACS_SETUP_DIR, "installed.db", 0);
411 char *ndbn = concat (root_dir, XEMACS_SETUP_DIR, "installed.db.new", 0);
412 char *sdbn = concat (root_dir, XEMACS_SETUP_DIR, "installed.db.old", 0);
416 FILE *odb = fopen (odbn, "rt");
417 FILE *ndb = fopen (ndbn, "wb");
421 char *err = strerror (errno);
423 err = "(unknown error)";
424 fatal (IDS_ERR_OPEN_WRITE, ndb, err);
429 char line[1000], pkg[1000];
431 while (fgets (line, 1000, odb))
434 sscanf (line, "%s", pkg);
435 for (i=0; i<npackages; i++)
437 if (strcmp (pkg, package[i].name) == 0)
438 switch (package[i].action)
442 case ACTION_UNINSTALL:
455 if (package[i].srcaction == SRCACTION_YES)
456 fprintf (ndb, "%s %s %d %s %d\n", package[i].name,
457 pi.install, pi.install_size,
458 pi.source, pi.source_size);
460 fprintf (ndb, "%s %s %d\n", package[i].name,
461 pi.install, pi.install_size);
469 if (odb && rename (odbn, sdbn))
470 badrename (odbn, sdbn);
473 if (rename (ndbn, odbn))
474 badrename (ndbn, odbn);
476 if (num_installs == 0 && num_uninstalls == 0)
478 exit_msg = IDS_NOTHING_INSTALLED;
481 if (num_installs == 0)
483 exit_msg = IDS_UNINSTALL_COMPLETE;
488 exit_msg = IDS_INSTALL_INCOMPLETE;
490 exit_msg = IDS_INSTALL_COMPLETE;