1 /*
2 * Portable package gateway for the ESP Package Manager (EPM).
3 *
4 * Copyright 1999-2017 by Michael R Sweet
5 * Copyright 1999-2010 by Easy Software Products.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18 /*
19 * Include necessary headers...
20 */
21
22 #include "epm.h"
23
24
25 /*
26 * Local functions...
27 */
28
29 static void clean_distfiles(const char *directory, const char *prodname,
30 const char *platname, dist_t *dist,
31 const char *subpackage);
32 static int write_combined(const char *title, const char *directory,
33 const char *prodname, const char *platname,
34 dist_t *dist, const char **files,
35 time_t deftime, const char *setup,
36 const char *types);
37 static int write_commands(dist_t *dist, FILE *fp, int type,
38 const char *subpackage);
39 static FILE *write_common(dist_t *dist, const char *title,
40 int rootsize, int usrsize,
41 const char *filename, const char *subpackage);
42 static int write_confcheck(FILE *fp);
43 static int write_depends(const char *prodname, dist_t *dist, FILE *fp,
44 const char *subpackage);
45 static int write_distfiles(const char *directory, const char *prodname,
46 const char *platname, dist_t *dist,
47 time_t deftime, const char *subpackage);
48 static int write_install(dist_t *dist, const char *prodname,
49 int rootsize, int usrsize,
50 const char *directory,
51 const char *subpackage);
52 static int write_instfiles(tarf_t *tarfile, const char *directory,
53 const char *prodname, const char *platname,
54 const char **files, const char *destdir,
55 const char *subpackage);
56 static int write_patch(dist_t *dist, const char *prodname,
57 int rootsize, int usrsize,
58 const char *directory,
59 const char *subpackage);
60 static int write_remove(dist_t *dist, const char *prodname,
61 int rootsize, int usrsize,
62 const char *directory,
63 const char *subpackage);
64 static int write_space_checks(const char *prodname, FILE *fp,
65 const char *sw, const char *ss,
66 int rootsize, int usrsize);
67
68
69 /*
70 * 'make_portable()' - Make a portable software distribution package.
71 */
72
73 int /* O - 1 = success, 0 = fail */
make_portable(const char * prodname,const char * directory,const char * platname,dist_t * dist,struct utsname * platform,const char * setup,const char * types)74 make_portable(const char *prodname, /* I - Product short name */
75 const char *directory,/* I - Directory for distribution files */
76 const char *platname, /* I - Platform name */
77 dist_t *dist, /* I - Distribution information */
78 struct utsname *platform, /* I - Platform information */
79 const char *setup, /* I - Setup GUI image */
80 const char *types) /* I - Setup GUI install types */
81 {
82 int i; /* Looping var */
83 int havepatchfiles; /* 1 if we have patch files, 0 otherwise */
84 time_t deftime; /* File creation time */
85 file_t *file; /* Software file */
86 static const char *distfiles[] = /* Distribution files */
87 {
88 "install",
89 "license",
90 "readme",
91 "remove",
92 "ss",
93 "sw",
94 NULL
95 };
96 static const char *patchfiles[] = /* Patch files */
97 {
98 "patch",
99 "license",
100 "pss",
101 "psw",
102 "readme",
103 "remove",
104 NULL
105 };
106
107
108 REF(platform);
109
110 if (Verbosity)
111 puts("Creating PORTABLE distribution...");
112
113 /*
114 * See if we need to make a patch distribution...
115 */
116
117 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
118 if (isupper((int)file->type))
119 break;
120
121 havepatchfiles = i > 0;
122
123 deftime = time(NULL);
124
125 /*
126 * Build the main package and all of the subpackages...
127 */
128
129 if (write_distfiles(directory, prodname, platname, dist, deftime, NULL))
130 return (1);
131
132 for (i = 0; i < dist->num_subpackages; i ++)
133 if (write_distfiles(directory, prodname, platname, dist, deftime,
134 dist->subpackages[i]))
135 return (1);
136
137 /*
138 * Create the distribution archives...
139 */
140
141 if (write_combined("distribution", directory, prodname, platname, dist,
142 distfiles, deftime, setup, types))
143 return (1);
144
145 if (havepatchfiles)
146 if (write_combined("patch", directory, prodname, platname, dist,
147 patchfiles, deftime, setup, types))
148 return (1);
149
150 /*
151 * Cleanup...
152 */
153
154 if (!KeepFiles)
155 {
156 clean_distfiles(directory, prodname, platname, dist, NULL);
157
158 for (i = 0; i < dist->num_subpackages; i ++)
159 clean_distfiles(directory, prodname, platname, dist,
160 dist->subpackages[i]);
161 }
162
163 /*
164 * Return!
165 */
166
167 return (0);
168 }
169
170
171 /*
172 * 'clean_distfiles()' - Remove temporary software distribution files...
173 */
174
175 static void
clean_distfiles(const char * directory,const char * prodname,const char * platname,dist_t * dist,const char * subpackage)176 clean_distfiles(const char *directory, /* I - Directory */
177 const char *prodname, /* I - Product name */
178 const char *platname, /* I - Platform name */
179 dist_t *dist, /* I - Distribution */
180 const char *subpackage) /* I - Subpackage */
181 {
182 char prodfull[255], /* Full name of product */
183 filename[1024]; /* Name of temporary file */
184
185
186 /*
187 * Figure out the full name of the distribution...
188 */
189
190 if (subpackage)
191 snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
192 else
193 strlcpy(prodfull, prodname, sizeof(prodfull));
194
195 /*
196 * Remove the distribution files...
197 */
198
199 if (Verbosity)
200 printf("Removing %s temporary files...\n", prodfull);
201
202 snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull);
203 unlink(filename);
204
205 snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull);
206 unlink(filename);
207
208 snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull);
209 unlink(filename);
210
211 snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull);
212 unlink(filename);
213
214 snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull);
215 unlink(filename);
216
217 snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull);
218 unlink(filename);
219
220 snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull);
221 unlink(filename);
222
223 snprintf(filename, sizeof(filename), "%s/%s.ss", directory, prodfull);
224 unlink(filename);
225
226 snprintf(filename, sizeof(filename), "%s/%s.sw", directory, prodfull);
227 unlink(filename);
228 }
229
230
231 /*
232 * 'write_combined()' - Write all of the distribution files in tar files.
233 */
234
235 static int /* O - 0 on success, -1 on failure */
write_combined(const char * title,const char * directory,const char * prodname,const char * platname,dist_t * dist,const char ** files,time_t deftime,const char * setup,const char * types)236 write_combined(const char *title, /* I - Title */
237 const char *directory, /* I - Output directory */
238 const char *prodname, /* I - Base product name */
239 const char *platname, /* I - Platform name */
240 dist_t *dist, /* I - Distribution */
241 const char **files, /* I - Files */
242 time_t deftime, /* I - Default timestamp */
243 const char *setup, /* I - Setup program */
244 const char *types) /* I - Setup types file */
245 {
246 int i; /* Looping var */
247 tarf_t *tarfile; /* Distribution tar file */
248 char tarfilename[1024], /* Name of tar file */
249 filename[1024]; /* Name of temporary file */
250 #ifdef __APPLE__
251 FILE *fp; /* Plist file... */
252 #endif /* __APPLE__ */
253 struct stat srcstat; /* Source file information */
254 const char *destdir; /* Destination directory */
255 const char *setup_img; /* Setup image name */
256
257
258 /*
259 * Figure out the filename...
260 */
261
262 if (dist->release[0])
263 snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s-%s", directory,
264 prodname, dist->version, dist->release);
265 else
266 snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s", directory, prodname,
267 dist->version);
268
269 if (!strcmp(title, "patch"))
270 strlcat(tarfilename, "-patch", sizeof(tarfilename));
271
272 if (platname[0])
273 {
274 strlcat(tarfilename, "-", sizeof(tarfilename));
275 strlcat(tarfilename, platname, sizeof(tarfilename));
276 }
277
278 strlcat(tarfilename, ".tar.gz", sizeof(tarfilename));
279
280 /*
281 * Open output file...
282 */
283
284 if ((tarfile = tar_open(tarfilename, 1)) == NULL)
285 {
286 fprintf(stderr, "epm: Unable to create output pipe to gzip -\n %s\n",
287 strerror(errno));
288 return (-1);
289 }
290
291 if (Verbosity)
292 printf("Writing %s archive:\n", title);
293
294 #ifdef __APPLE__
295 if (setup)
296 {
297 /*
298 * Create directories for the setup application...
299 */
300
301 if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
302 "Install.app", NULL) < 0)
303 {
304 tar_close(tarfile);
305 return (-1);
306 }
307
308 if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
309 "Install.app/Contents", NULL) < 0)
310 {
311 tar_close(tarfile);
312 return (-1);
313 }
314
315 if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
316 "Install.app/Contents/MacOS", NULL) < 0)
317 {
318 tar_close(tarfile);
319 return (-1);
320 }
321
322 if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
323 "Install.app/Contents/Resources", NULL) < 0)
324 {
325 tar_close(tarfile);
326 return (-1);
327 }
328
329 /*
330 * Then copy the data files...
331 */
332
333 snprintf(filename, sizeof(filename), "%s/default.icns", DataDir);
334 stat(filename, &srcstat);
335
336 if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
337 srcstat.st_size, srcstat.st_mtime, "root", "root",
338 "Install.app/Contents/Resources/setup.icns", NULL) < 0)
339 {
340 tar_close(tarfile);
341 return (-1);
342 }
343
344 if (tar_file(tarfile, filename) < 0)
345 {
346 tar_close(tarfile);
347 return (-1);
348 }
349
350 if (Verbosity)
351 printf(" %7.0fk setup.icns\n", (srcstat.st_size + 1023) / 1024.0);
352
353 snprintf(filename, sizeof(filename), "%s/%s.setup.plist", directory,
354 prodname);
355 if ((fp = fopen(filename, "w")) == NULL)
356 {
357 fprintf(stderr, "epm: Error writing %s -\n %s\n", filename,
358 strerror(errno));
359 tar_close(tarfile);
360 return (-1);
361 }
362
363 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
364 "<plist version=\"0.9\">\n"
365 " <dict>\n"
366 " <key>CFBundleInfoDictionaryVersion</key>\n"
367 " <string>6.0</string>\n"
368 " <key>CFBundleExecutable</key>\n"
369 " <string>setup</string>\n"
370 " <key>CFBundleIdentifier</key>\n"
371 " <string>org.msweet.epmsetup</string>\n"
372 " <key>CFBundleVersion</key>\n"
373 " <string>%s</string>\n"
374 " <key>CFBundleDevelopmentRegion</key>\n"
375 " <string>English</string>\n"
376 " <key>NSHumanReadableCopyright</key>\n"
377 " <string>Copyright %s</string>\n"
378 " <key>CFAppleHelpAnchor</key>\n"
379 " <string>help</string>\n"
380 " <key>CFBundleName</key>\n"
381 " <string>Installer for %s</string>\n"
382 " <key>CFBundlePackageType</key>\n"
383 " <string>APPL</string>\n"
384 " <key>CFBundleSignature</key>\n"
385 " <string>FLTK</string>\n"
386 " <key>CFBundleIconFile</key>\n"
387 " <string>setup.icns</string>\n"
388 " <key>CFBundleShortVersionString</key>\n"
389 " <string>%s</string>\n"
390 " <key>CFBundleGetInfoString</key>\n"
391 " <string>%s, Copyright %s</string>\n"
392 " </dict>\n"
393 "</plist>\n",
394 dist->version,
395 dist->copyright,
396 dist->product,
397 dist->version,
398 dist->version, dist->copyright);
399 fclose(fp);
400
401 stat(filename, &srcstat);
402
403 if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
404 srcstat.st_size, srcstat.st_mtime, "root", "root",
405 "Install.app/Contents/Info.plist", NULL) < 0)
406 {
407 tar_close(tarfile);
408 return (-1);
409 }
410
411 if (tar_file(tarfile, filename) < 0)
412 {
413 tar_close(tarfile);
414 return (-1);
415 }
416
417 if (!KeepFiles)
418 unlink(filename);
419
420 if (Verbosity)
421 printf(" %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0);
422 }
423
424 destdir = "Install.app/Contents/Resources/";
425
426 #else /* !__APPLE__ */
427 destdir = "";
428 #endif /* __APPLE__ */
429
430 /*
431 * Write installer files...
432 */
433
434 if (write_instfiles(tarfile, directory, prodname, platname, files, destdir,
435 NULL))
436 {
437 tar_close(tarfile);
438 return (-1);
439 }
440
441 for (i = 0; i < dist->num_subpackages; i ++)
442 if (write_instfiles(tarfile, directory, prodname, platname, files, destdir,
443 dist->subpackages[i]))
444 {
445 tar_close(tarfile);
446 return (-1);
447 }
448
449 /*
450 * Now the setup files...
451 */
452
453 if (setup)
454 {
455 /*
456 * Include the ESP Software Installation Wizard (setup)...
457 */
458
459 if (stat(SetupProgram, &srcstat))
460 {
461 fprintf(stderr, "epm: Unable to stat GUI setup program %s: %s\n", SetupProgram, strerror(errno));
462 tar_close(tarfile);
463 return (-1);
464 }
465
466 #ifdef __APPLE__
467 if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
468 srcstat.st_mtime, "root", "root",
469 "Install.app/Contents/MacOS/setup", NULL) < 0)
470 #else
471 if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
472 srcstat.st_mtime, "root", "root", "setup", NULL) < 0)
473 #endif /* __APPLE__ */
474 {
475 tar_close(tarfile);
476 return (-1);
477 }
478
479 if (tar_file(tarfile, SetupProgram) < 0)
480 {
481 tar_close(tarfile);
482 return (-1);
483 }
484
485 if (Verbosity)
486 printf(" %7.0fk setup\n", (srcstat.st_size + 1023) / 1024.0);
487
488 /*
489 * And the image file...
490 */
491
492 stat(setup, &srcstat);
493
494 if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".gif"))
495 setup_img = "setup.gif";
496 else if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".jpg"))
497 setup_img = "setup.jpg";
498 else if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".png"))
499 setup_img = "setup.png";
500 else
501 setup_img = "setup.xpm";
502
503 snprintf(filename, sizeof(filename), "%s%s", destdir, setup_img);
504
505 if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size,
506 srcstat.st_mtime, "root", "root", filename, NULL) < 0)
507 {
508 tar_close(tarfile);
509 return (-1);
510 }
511
512 if (tar_file(tarfile, setup) < 0)
513 {
514 tar_close(tarfile);
515 return (-1);
516 }
517
518 if (Verbosity)
519 printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img);
520
521 /*
522 * And the types file...
523 */
524
525 if (types)
526 {
527 stat(types, &srcstat);
528 snprintf(filename, sizeof(filename), "%ssetup.types", destdir);
529
530 if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size,
531 srcstat.st_mtime, "root", "root", filename, NULL) < 0)
532 {
533 tar_close(tarfile);
534 return (-1);
535 }
536
537 if (tar_file(tarfile, types) < 0)
538 {
539 tar_close(tarfile);
540 return (-1);
541 }
542
543 if (Verbosity)
544 printf(" %7.0fk setup.types\n", (srcstat.st_size + 1023) / 1024.0);
545 }
546
547 /*
548 * And finally the uninstall stuff...
549 */
550
551 #ifdef __APPLE__
552 if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
553 "Uninstall.app", NULL) < 0)
554 {
555 tar_close(tarfile);
556 return (-1);
557 }
558
559 if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
560 "Uninstall.app/Contents", NULL) < 0)
561 {
562 tar_close(tarfile);
563 return (-1);
564 }
565
566 if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
567 "Uninstall.app/Contents/MacOS", NULL) < 0)
568 {
569 tar_close(tarfile);
570 return (-1);
571 }
572
573 if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
574 "Uninstall.app/Contents/Resources", NULL) < 0)
575 {
576 tar_close(tarfile);
577 return (-1);
578 }
579
580 /*
581 * Then copy the data files...
582 */
583
584 snprintf(filename, sizeof(filename), "%s/default.icns", DataDir);
585 stat(filename, &srcstat);
586
587 if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
588 srcstat.st_size, srcstat.st_mtime, "root", "root",
589 "Uninstall.app/Contents/Resources/uninst.icns", NULL) < 0)
590 {
591 tar_close(tarfile);
592 return (-1);
593 }
594
595 if (tar_file(tarfile, filename) < 0)
596 {
597 tar_close(tarfile);
598 return (-1);
599 }
600
601 if (Verbosity)
602 printf(" %7.0fk uninst.icns\n", (srcstat.st_size + 1023) / 1024.0);
603
604 snprintf(filename, sizeof(filename), "%s/%s.uninst.plist", directory,
605 prodname);
606 if ((fp = fopen(filename, "w")) == NULL)
607 {
608 fprintf(stderr, "epm: Error writing %s -\n %s\n", filename,
609 strerror(errno));
610 tar_close(tarfile);
611 return (-1);
612 }
613
614 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
615 "<plist version=\"0.9\">\n"
616 " <dict>\n"
617 " <key>CFBundleInfoDictionaryVersion</key>\n"
618 " <string>6.0</string>\n"
619 " <key>CFBundleExecutable</key>\n"
620 " <string>uninst</string>\n"
621 " <key>CFBundleIdentifier</key>\n"
622 " <string>org.msweet.epmuninst</string>\n"
623 " <key>CFBundleVersion</key>\n"
624 " <string>%s</string>\n"
625 " <key>CFBundleDevelopmentRegion</key>\n"
626 " <string>English</string>\n"
627 " <key>NSHumanReadableCopyright</key>\n"
628 " <string>Copyright %s</string>\n"
629 " <key>CFAppleHelpAnchor</key>\n"
630 " <string>help</string>\n"
631 " <key>CFBundleName</key>\n"
632 " <string>Uninstaller for %s</string>\n"
633 " <key>CFBundlePackageType</key>\n"
634 " <string>APPL</string>\n"
635 " <key>CFBundleSignature</key>\n"
636 " <string>FLTK</string>\n"
637 " <key>CFBundleIconFile</key>\n"
638 " <string>uninst.icns</string>\n"
639 " <key>CFBundleShortVersionString</key>\n"
640 " <string>%s</string>\n"
641 " <key>CFBundleGetInfoString</key>\n"
642 " <string>%s, Copyright %s</string>\n"
643 " </dict>\n"
644 "</plist>\n",
645 dist->version,
646 dist->copyright,
647 dist->product,
648 dist->version,
649 dist->version, dist->copyright);
650 fclose(fp);
651
652 stat(filename, &srcstat);
653
654 if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
655 srcstat.st_size, srcstat.st_mtime, "root", "root",
656 "Uninstall.app/Contents/Info.plist", NULL) < 0)
657 {
658 tar_close(tarfile);
659 return (-1);
660 }
661
662 if (tar_file(tarfile, filename) < 0)
663 {
664 tar_close(tarfile);
665 return (-1);
666 }
667
668 if (!KeepFiles)
669 unlink(filename);
670
671 if (Verbosity)
672 printf(" %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0);
673 #endif /* __APPLE__ */
674
675 /*
676 * Include the ESP Software Removal Wizard (uninst)...
677 */
678
679 if (stat(UninstProgram, &srcstat))
680 {
681 fprintf(stderr, "epm: Unable to stat GUI uninstall program %s: %s\n", UninstProgram, strerror(errno));
682 tar_close(tarfile);
683 return (-1);
684 }
685
686 #ifdef __APPLE__
687 if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
688 srcstat.st_mtime, "root", "root",
689 "Uninstall.app/Contents/MacOS/uninst", NULL) < 0)
690 #else
691 if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
692 srcstat.st_mtime, "root", "root", "uninst", NULL) < 0)
693 #endif /* __APPLE__ */
694 {
695 tar_close(tarfile);
696 return (-1);
697 }
698
699 if (tar_file(tarfile, UninstProgram) < 0)
700 {
701 tar_close(tarfile);
702 return (-1);
703 }
704
705 if (Verbosity)
706 printf(" %7.0fk uninst\n", (srcstat.st_size + 1023) / 1024.0);
707
708 #ifdef __APPLE__
709 /*
710 * And the image file...
711 */
712
713 stat(setup, &srcstat);
714
715 snprintf(filename, sizeof(filename), "Uninstall.app/Contents/Resources/%s",
716 setup_img);
717
718 if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size,
719 srcstat.st_mtime, "root", "root", filename, NULL) < 0)
720 {
721 tar_close(tarfile);
722 return (-1);
723 }
724
725 if (tar_file(tarfile, setup) < 0)
726 {
727 tar_close(tarfile);
728 return (-1);
729 }
730
731 if (Verbosity)
732 printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img);
733 #endif /* __APPLE__ */
734 }
735
736 if (Verbosity)
737 {
738 puts(" ------- ----------------------------------------");
739 printf(" %7.0fk %s-%s", tarfile->blocks * 0.5f, prodname, dist->version);
740 if (dist->release[0])
741 printf("-%s", dist->release);
742 if (!strcmp(title, "patch"))
743 fputs("-patch", stdout);
744 if (platname[0])
745 printf("-%s", platname);
746 puts(".tar");
747 }
748
749 tar_close(tarfile);
750
751 if (Verbosity)
752 {
753 stat(tarfilename, &srcstat);
754
755 puts(" ------- ----------------------------------------");
756 printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0,
757 tarfilename);
758 }
759
760 #ifdef __APPLE__
761 {
762 char dmgfilename[1024]; /* Disk image filename */
763
764
765 /*
766 * Make a disk image containing the package files...
767 */
768
769 if (dist->release[0])
770 snprintf(filename, sizeof(filename), "%s/%s-%s-%s", directory, prodname,
771 dist->version, dist->release);
772 else
773 snprintf(filename, sizeof(filename), "%s/%s-%s", directory, prodname,
774 dist->version);
775
776 if (!strcmp(title, "patch"))
777 strlcat(filename, "-patch", sizeof(filename));
778
779 if (platname[0])
780 {
781 strlcat(filename, "-", sizeof(filename));
782 strlcat(filename, platname, sizeof(filename));
783 }
784
785 snprintf(dmgfilename, sizeof(dmgfilename), "%s.dmg", filename);
786
787 mkdir(filename, 0777);
788
789 if (run_command(filename, "tar xvzf ../%s", strrchr(tarfilename, '/') + 1))
790 {
791 fputs("epm: Unable to create disk image template folder!\n", stderr);
792 return (1);
793 }
794
795 if (run_command(NULL, "hdiutil create -ov -srcfolder %s %s",
796 filename, dmgfilename))
797 {
798 fputs("epm: Unable to create disk image!\n", stderr);
799 return (1);
800 }
801
802 if (!KeepFiles)
803 unlink_directory(filename);
804
805 if (Verbosity)
806 {
807 stat(dmgfilename, &srcstat);
808
809 printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0,
810 dmgfilename);
811 }
812 }
813 #endif /* __APPLE__ */
814
815 return (0);
816 }
817
818
819 /*
820 * 'write_commands()' - Write commands.
821 */
822
823 static int /* O - 0 on success, -1 on failure */
write_commands(dist_t * dist,FILE * fp,int type,const char * subpackage)824 write_commands(dist_t *dist, /* I - Distribution */
825 FILE *fp, /* I - File pointer */
826 int type, /* I - Type of commands to write */
827 const char *subpackage) /* I - Subsystem */
828 {
829 int i; /* Looping var */
830 command_t *c; /* Current command */
831 static const char *commands[] = /* Command strings */
832 {
833 "pre-install",
834 "post-install",
835 "pre-patch",
836 "post-patch",
837 "pre-remove",
838 "post-remove"
839 };
840
841
842 for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
843 if (c->type == type && c->subpackage == subpackage)
844 break;
845
846 if (i)
847 {
848 fprintf(fp, "echo Running %s commands...\n", commands[type]);
849
850 for (; i > 0; i --, c ++)
851 if (c->type == type && c->subpackage == subpackage)
852 if (fprintf(fp, "%s\n", c->command) < 1)
853 {
854 perror("epm: Error writing command");
855 return (-1);
856 }
857 }
858
859 return (0);
860 }
861
862
863 /*
864 * 'write_common()' - Write the common shell script header.
865 */
866
867 static FILE * /* O - File pointer */
write_common(dist_t * dist,const char * title,int rootsize,int usrsize,const char * filename,const char * subpackage)868 write_common(dist_t *dist, /* I - Distribution */
869 const char *title, /* I - "Installation", etc... */
870 int rootsize, /* I - Size of root files in kbytes */
871 int usrsize, /* I - Size of /usr files in kbytes */
872 const char *filename, /* I - Script to create */
873 const char *subpackage) /* I - Subpackage name */
874 {
875 int i; /* Looping var */
876 FILE *fp; /* File pointer */
877 char line[1024], /* Line buffer */
878 *start, /* Start of line */
879 *ptr; /* Pointer into line */
880
881
882 /*
883 * Remove any existing copy of the file...
884 */
885
886 unlink(filename);
887
888 /*
889 * Create the script file...
890 */
891
892 if ((fp = fopen(filename, "w")) == NULL)
893 return (NULL);
894
895 /*
896 * Update the permissions on the file...
897 */
898
899 fchmod(fileno(fp), 0755);
900
901 /*
902 * Write the standard header...
903 */
904
905 fputs("#!/bin/sh\n", fp);
906 fprintf(fp, "# %s script for %s version %s.\n", title,
907 dist->product, dist->version);
908 fputs("# Produced using " EPM_VERSION " (https://michaelrsweet.github.io/epm).\n", fp);
909 fprintf(fp, "#%%product %s", dist->product);
910 if (subpackage)
911 {
912 for (i = 0; i < dist->num_descriptions; i ++)
913 if (dist->descriptions[i].subpackage == subpackage)
914 break;
915
916 if (i < dist->num_descriptions)
917 {
918 strlcpy(line, dist->descriptions[i].description, sizeof(line));
919 if ((ptr = strchr(line, '\n')) != NULL)
920 *ptr = '\0';
921
922 fprintf(fp, " - %s", line);
923 }
924 }
925 fputs("\n", fp);
926 fprintf(fp, "#%%vendor %s\n", dist->vendor);
927 fprintf(fp, "#%%copyright %s\n", dist->copyright);
928 fprintf(fp, "#%%version %s %d\n", dist->version, dist->vernumber);
929
930 for (i = 0; i < dist->num_descriptions; i ++)
931 if (dist->descriptions[i].subpackage == subpackage)
932 break;
933
934 if (i < dist->num_descriptions)
935 {
936 /*
937 * Just do descriptions for this subpackage...
938 */
939
940 for (; i < dist->num_descriptions; i ++)
941 if (dist->descriptions[i].subpackage == subpackage)
942 {
943 strlcpy(line, dist->descriptions[i].description, sizeof(line));
944
945 for (start = line; start; start = ptr)
946 {
947 if ((ptr = strchr(start, '\n')) != NULL)
948 *ptr++ = '\0';
949
950 fprintf(fp, "#%%description %s\n", start);
951 }
952 }
953 }
954 else
955 {
956 /*
957 * Just do descriptions for the main package...
958 */
959
960 for (i = 0; i < dist->num_descriptions; i ++)
961 if (dist->descriptions[i].subpackage == NULL)
962 {
963 strlcpy(line, dist->descriptions[i].description, sizeof(line));
964
965 for (start = line; start; start = ptr)
966 {
967 if ((ptr = strchr(start, '\n')) != NULL)
968 *ptr++ = '\0';
969
970 fprintf(fp, "#%%description %s\n", start);
971 }
972 }
973 }
974
975 fprintf(fp, "#%%rootsize %d\n", rootsize);
976 fprintf(fp, "#%%usrsize %d\n", usrsize);
977 fputs("#\n", fp);
978
979 fputs("PATH=/usr/gnu/bin:/usr/xpg4/bin:/bin:/usr/bin:/usr/ucb:${PATH}\n", fp);
980 fputs("SHELL=/bin/sh\n", fp);
981 fputs("case \"`uname`\" in\n", fp);
982 fputs("\tDarwin*)\n", fp);
983 fputs("\tcase \"`id -un`\" in\n", fp);
984 fputs("\t\troot)\n", fp);
985 fputs("\t\t;;\n", fp);
986 fputs("\t\t*)\n", fp);
987 fprintf(fp, "\t\techo Sorry, you must have administrative priviledges to %s this software.\n",
988 title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch");
989 fputs("\t\texit 1\n", fp);
990 fputs("\t\t;;\n", fp);
991 fputs("\tesac\n", fp);
992 fputs("\t;;\n", fp);
993 fputs("\t*)\n", fp);
994 fputs("\tcase \"`id`\" in\n", fp);
995 fputs("\t\tuid=0*)\n", fp);
996 fputs("\t\t;;\n", fp);
997 fputs("\t\t*)\n", fp);
998 fprintf(fp, "\t\techo Sorry, you must be root to %s this software.\n",
999 title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch");
1000 fputs("\t\texit 1\n", fp);
1001 fputs("\t\t;;\n", fp);
1002 fputs("\tesac\n", fp);
1003 fputs("\t;;\n", fp);
1004 fputs("esac\n", fp);
1005
1006 qprintf(fp, "echo Copyright %s\n", dist->copyright);
1007 fprintf(fp, "# Reset umask for %s...\n",
1008 title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch");
1009 fputs("umask 002\n", fp);
1010
1011 write_confcheck(fp);
1012
1013 /*
1014 * Return the file pointer...
1015 */
1016
1017 return (fp);
1018 }
1019
1020
1021 /*
1022 * 'write_confcheck()' - Write the echo check to find the right echo options.
1023 */
1024
1025 static int /* O - -1 on error, 0 on success */
write_confcheck(FILE * fp)1026 write_confcheck(FILE *fp) /* I - Script file */
1027 {
1028 /*
1029 * This is a simplified version of the autoconf test for echo; basically
1030 * we ignore the Stardent Vistra SVR4 case, since 1) we've never heard of
1031 * this OS, and 2) it doesn't provide the same functionality, specifically
1032 * the omission of a newline when prompting the user for some text.
1033 */
1034
1035 fputs("# Determine correct echo options...\n", fp);
1036 fputs("if (echo \"testing\\c\"; echo 1,2,3) | grep c >/dev/null; then\n", fp);
1037 fputs(" ac_n=-n\n", fp);
1038 fputs(" ac_c=\n", fp);
1039 fputs("else\n", fp);
1040 fputs(" ac_n=\n", fp);
1041 fputs(" ac_c='\\c'\n", fp);
1042 fputs("fi\n", fp);
1043
1044 /*
1045 * This is a check for the correct options to use with the "tar"
1046 * command.
1047 */
1048
1049 fputs("# Determine correct extract options for the tar command...\n", fp);
1050 fputs("if test `uname` = Darwin; then\n", fp);
1051 fputs(" ac_tar=\"tar -xpPf\"\n", fp);
1052 fputs("elif test \"`tar --help 2>&1 | grep GNU`\" = \"\"; then\n", fp);
1053 fputs(" ac_tar=\"tar -xpf\"\n", fp);
1054 fputs("else\n", fp);
1055 fputs(" ac_tar=\"tar -xpPf\"\n", fp);
1056 fputs("fi\n", fp);
1057
1058 return (0);
1059 }
1060
1061
1062 /*
1063 * 'write_depends()' - Write dependencies.
1064 */
1065
1066 static int /* O - 0 on success, - 1 on failure */
write_depends(const char * prodname,dist_t * dist,FILE * fp,const char * subpackage)1067 write_depends(const char *prodname, /* I - Product name */
1068 dist_t *dist, /* I - Distribution */
1069 FILE *fp, /* I - File pointer */
1070 const char *subpackage) /* I - Subpackage */
1071 {
1072 int i; /* Looping var */
1073 depend_t *d; /* Current dependency */
1074 const char *product; /* Product/file to depend on */
1075 static const char *depends[] = /* Dependency strings */
1076 {
1077 "requires",
1078 "incompat",
1079 "replaces",
1080 "provides"
1081 };
1082
1083
1084 for (i = 0, d = dist->depends; i < dist->num_depends; i ++, d ++)
1085 if (d->subpackage == subpackage)
1086 {
1087 if (!strcmp(d->product, "_self"))
1088 product = prodname;
1089 else
1090 product = d->product;
1091
1092 fprintf(fp, "#%%%s %s %d %d\n", depends[(int)d->type], product,
1093 d->vernumber[0], d->vernumber[1]);
1094
1095 switch (d->type)
1096 {
1097 case DEPEND_REQUIRES :
1098 if (product[0] == '/')
1099 {
1100 /*
1101 * Require a file...
1102 */
1103
1104 qprintf(fp, "if test ! -r %s -a ! -h %s; then\n",
1105 product, product);
1106 qprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n",
1107 product);
1108 fputs(" exit 1\n", fp);
1109 fputs("fi\n", fp);
1110 }
1111 else
1112 {
1113 /*
1114 * Require a product...
1115 */
1116
1117 fprintf(fp, "if test ! -x %s/%s.remove; then\n",
1118 SoftwareDir, product);
1119 fprintf(fp, " if test -x %s.install; then\n",
1120 product);
1121 fprintf(fp, " echo Installing required %s software...\n",
1122 product);
1123 fprintf(fp, " ./%s.install now\n", product);
1124 fputs(" else\n", fp);
1125 fprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n",
1126 product);
1127 fputs(" exit 1\n", fp);
1128 fputs(" fi\n", fp);
1129 fputs("fi\n", fp);
1130
1131 if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX)
1132 {
1133 /*
1134 * Do version number checking...
1135 */
1136
1137 fprintf(fp, "installed=`grep \'^#%%version\' "
1138 "%s/%s.remove | awk \'{print $3}\'`\n",
1139 SoftwareDir, product);
1140
1141 fputs("if test x$installed = x; then\n", fp);
1142 fputs(" installed=0\n", fp);
1143 fputs("fi\n", fp);
1144
1145 fprintf(fp, "if test $installed -lt %d -o $installed -gt %d; then\n",
1146 d->vernumber[0], d->vernumber[1]);
1147 fprintf(fp, " if test -x %s.install; then\n",
1148 product);
1149 fprintf(fp, " echo Installing required %s software...\n",
1150 product);
1151 fprintf(fp, " ./%s.install now\n", product);
1152 fputs(" else\n", fp);
1153 fprintf(fp, " echo Sorry, you must first install \\'%s\\' version %s to %s!\n",
1154 product, d->version[0], d->version[1]);
1155 fputs(" exit 1\n", fp);
1156 fputs(" fi\n", fp);
1157 fputs("fi\n", fp);
1158 }
1159 }
1160 break;
1161
1162 case DEPEND_INCOMPAT :
1163 if (product[0] == '/')
1164 {
1165 /*
1166 * Incompatible with a file...
1167 */
1168
1169 qprintf(fp, "if test -r %s -o -h %s; then\n",
1170 product, product);
1171 qprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n",
1172 product);
1173 fputs(" echo Please remove it first.\n", fp);
1174 fputs(" exit 1\n", fp);
1175 fputs("fi\n", fp);
1176 }
1177 else
1178 {
1179 /*
1180 * Incompatible with a product...
1181 */
1182
1183 fprintf(fp, "if test -x %s/%s.remove; then\n",
1184 SoftwareDir, product);
1185
1186 if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX)
1187 {
1188 /*
1189 * Do version number checking...
1190 */
1191
1192 fprintf(fp, " installed=`grep \'^#%%version\' "
1193 "%s/%s.remove | awk \'{print $3}\'`\n",
1194 SoftwareDir, product);
1195
1196 fputs(" if test x$installed = x; then\n", fp);
1197 fputs(" installed=0\n", fp);
1198 fputs(" fi\n", fp);
1199
1200 fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n",
1201 d->vernumber[0], d->vernumber[1]);
1202 fprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\' version %s to %s!\n",
1203 product, d->version[0], d->version[1]);
1204 fprintf(fp, " echo Please remove it first by running \\'%s/%s.remove\\'.\n",
1205 SoftwareDir, product);
1206 fputs(" exit 1\n", fp);
1207 fputs(" fi\n", fp);
1208 }
1209 else
1210 {
1211 fprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n",
1212 product);
1213 fprintf(fp, " echo Please remove it first by running \\'%s/%s.remove\\'.\n",
1214 SoftwareDir, product);
1215 fputs(" exit 1\n", fp);
1216 }
1217
1218 fputs("fi\n", fp);
1219 }
1220 break;
1221
1222 case DEPEND_REPLACES :
1223 fprintf(fp, "if test -x %s/%s.remove; then\n", SoftwareDir,
1224 product);
1225
1226 if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX)
1227 {
1228 /*
1229 * Do version number checking...
1230 */
1231
1232 fprintf(fp, " installed=`grep \'^#%%version\' "
1233 "%s/%s.remove | awk \'{print $3}\'`\n",
1234 SoftwareDir, product);
1235
1236 fputs(" if test x$installed = x; then\n", fp);
1237 fputs(" installed=0\n", fp);
1238 fputs(" fi\n", fp);
1239
1240 fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n",
1241 d->vernumber[0], d->vernumber[1]);
1242 fprintf(fp, " echo Automatically replacing \\'%s\\'...\n",
1243 product);
1244 fprintf(fp, " %s/%s.remove now\n",
1245 SoftwareDir, product);
1246 fputs(" fi\n", fp);
1247 }
1248 else
1249 {
1250 fprintf(fp, " echo Automatically replacing \\'%s\\'...\n",
1251 product);
1252 fprintf(fp, " %s/%s.remove now\n",
1253 SoftwareDir, product);
1254 }
1255
1256 fputs("fi\n", fp);
1257 break;
1258 }
1259 }
1260
1261 return (0);
1262 }
1263
1264
1265 /*
1266 * 'write_distfiles()' - Write a software distribution...
1267 */
1268
1269 static int /* O - -1 on error, 0 on success */
write_distfiles(const char * directory,const char * prodname,const char * platname,dist_t * dist,time_t deftime,const char * subpackage)1270 write_distfiles(const char *directory, /* I - Directory */
1271 const char *prodname, /* I - Product name */
1272 const char *platname, /* I - Platform name */
1273 dist_t *dist, /* I - Distribution */
1274 time_t deftime, /* I - Default file time */
1275 const char *subpackage) /* I - Subpackage */
1276 {
1277 int i; /* Looping var */
1278 int havepatchfiles; /* 1 if we have patch files, 0 otherwise */
1279 tarf_t *tarfile; /* Distribution tar file */
1280 char prodfull[255], /* Full name of product */
1281 swname[255], /* Name of distribution tar file */
1282 pswname[255], /* Name of patch tar file */
1283 filename[1024]; /* Name of temporary file */
1284 struct stat srcstat; /* Source file information */
1285 file_t *file; /* Software file */
1286 int rootsize, /* Size of files in root partition */
1287 usrsize; /* Size of files in /usr partition */
1288 int prootsize, /* Size of patch files in root partition */
1289 pusrsize; /* Size of patch files in /usr partition */
1290
1291
1292 /*
1293 * Figure out the full name of the distribution...
1294 */
1295
1296 if (subpackage)
1297 snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
1298 else
1299 strlcpy(prodfull, prodname, sizeof(prodfull));
1300
1301 /*
1302 * See if we need to make a patch distribution...
1303 */
1304
1305 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1306 if (isupper((int)file->type) && file->subpackage == subpackage)
1307 break;
1308
1309 havepatchfiles = i > 0;
1310
1311 /*
1312 * Copy the license and readme files...
1313 */
1314
1315 if (Verbosity)
1316 printf("Copying %s license and readme files...\n", prodfull);
1317
1318 if (dist->license[0])
1319 {
1320 snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull);
1321 if (copy_file(filename, dist->license, 0444, getuid(), getgid()))
1322 return (1);
1323 }
1324
1325 if (dist->readme[0])
1326 {
1327 snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull);
1328 if (copy_file(filename, dist->readme, 0444, getuid(), getgid()))
1329 return (1);
1330 }
1331
1332 /*
1333 * Create the non-shared software distribution file...
1334 */
1335
1336 if (Verbosity)
1337 puts("Creating non-shared software distribution file...");
1338
1339 snprintf(swname, sizeof(swname), "%s.sw", prodfull);
1340 snprintf(filename, sizeof(filename), "%s/%s", directory, swname);
1341
1342 unlink(filename);
1343 if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
1344 {
1345 fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n",
1346 filename, strerror(errno));
1347 return (1);
1348 }
1349
1350 for (i = dist->num_files, file = dist->files, rootsize = 0, prootsize = 0;
1351 i > 0;
1352 i --, file ++)
1353 if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
1354 switch (tolower(file->type))
1355 {
1356 case 'f' : /* Regular file */
1357 case 'c' : /* Config file */
1358 case 'i' : /* Init script */
1359 if (stat(file->src, &srcstat))
1360 {
1361 fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
1362 tar_close(tarfile);
1363 return (1);
1364 }
1365
1366 rootsize += (srcstat.st_size + 1023) / 1024;
1367
1368 if (isupper(file->type & 255))
1369 prootsize += (srcstat.st_size + 1023) / 1024;
1370
1371 /*
1372 * Configuration files are extracted to the config file name with
1373 * .N appended; add a bit of script magic to check if the config
1374 * file already exists, and if not we copy the .N to the config
1375 * file location...
1376 */
1377
1378 if (tolower(file->type) == 'c')
1379 snprintf(filename, sizeof(filename), "%s.N", file->dst);
1380 else if (tolower(file->type) == 'i')
1381 snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir,
1382 file->dst);
1383 else
1384 strlcpy(filename, file->dst, sizeof(filename));
1385
1386 if (Verbosity > 1)
1387 printf("%s -> %s...\n", file->src, filename);
1388
1389 if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
1390 srcstat.st_mtime, file->user, file->group,
1391 filename, NULL) < 0)
1392 {
1393 tar_close(tarfile);
1394 return (1);
1395 }
1396
1397 if (tar_file(tarfile, file->src) < 0)
1398 {
1399 tar_close(tarfile);
1400 return (1);
1401 }
1402 break;
1403
1404 case 'd' : /* Create directory */
1405 if (Verbosity > 1)
1406 printf("Directory %s...\n", file->dst);
1407
1408 rootsize ++;
1409
1410 if (isupper(file->type & 255))
1411 prootsize ++;
1412 break;
1413
1414 case 'l' : /* Link file */
1415 if (Verbosity > 1)
1416 printf("%s -> %s...\n", file->src, file->dst);
1417
1418 if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
1419 file->user, file->group, file->dst, file->src) < 0)
1420 {
1421 tar_close(tarfile);
1422 return (1);
1423 }
1424
1425 rootsize ++;
1426
1427 if (isupper(file->type & 255))
1428 prootsize ++;
1429 break;
1430 }
1431
1432 tar_close(tarfile);
1433
1434 /*
1435 * Create the shared software distribution file...
1436 */
1437
1438 if (Verbosity)
1439 puts("Creating shared software distribution file...");
1440
1441 snprintf(swname, sizeof(swname), "%s.ss", prodfull);
1442 snprintf(filename, sizeof(filename), "%s/%s", directory, swname);
1443
1444 unlink(filename);
1445 if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
1446 {
1447 fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n",
1448 filename, strerror(errno));
1449 return (1);
1450 }
1451
1452 for (i = dist->num_files, file = dist->files, usrsize = 0, pusrsize = 0;
1453 i > 0;
1454 i --, file ++)
1455 if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
1456 switch (tolower(file->type))
1457 {
1458 case 'f' : /* Regular file */
1459 case 'c' : /* Config file */
1460 case 'i' : /* Init script */
1461 if (stat(file->src, &srcstat))
1462 {
1463 fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
1464 tar_close(tarfile);
1465 return (1);
1466 }
1467
1468 usrsize += (srcstat.st_size + 1023) / 1024;
1469
1470 if (isupper(file->type & 255))
1471 pusrsize += (srcstat.st_size + 1023) / 1024;
1472
1473 /*
1474 * Configuration files are extracted to the config file name with
1475 * .N appended; add a bit of script magic to check if the config
1476 * file already exists, and if not we copy the .N to the config
1477 * file location...
1478 */
1479
1480 if (tolower(file->type) == 'c')
1481 snprintf(filename, sizeof(filename), "%s.N", file->dst);
1482 else if (tolower(file->type) == 'i')
1483 snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir,
1484 file->dst);
1485 else
1486 strlcpy(filename, file->dst, sizeof(filename));
1487
1488 if (Verbosity > 1)
1489 printf("%s -> %s...\n", file->src, filename);
1490
1491 if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
1492 srcstat.st_mtime, file->user, file->group,
1493 filename, NULL) < 0)
1494 {
1495 tar_close(tarfile);
1496 return (1);
1497 }
1498
1499 if (tar_file(tarfile, file->src) < 0)
1500 {
1501 tar_close(tarfile);
1502 return (1);
1503 }
1504 break;
1505
1506 case 'd' : /* Create directory */
1507 if (Verbosity > 1)
1508 printf("%s...\n", file->dst);
1509
1510 usrsize ++;
1511
1512 if (isupper(file->type & 255))
1513 pusrsize ++;
1514 break;
1515
1516 case 'l' : /* Link file */
1517 if (Verbosity > 1)
1518 printf("%s -> %s...\n", file->src, file->dst);
1519
1520 if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
1521 file->user, file->group, file->dst, file->src) < 0)
1522 {
1523 tar_close(tarfile);
1524 return (1);
1525 }
1526
1527 usrsize ++;
1528
1529 if (isupper(file->type & 255))
1530 pusrsize ++;
1531 break;
1532 }
1533
1534 tar_close(tarfile);
1535
1536 /*
1537 * Create the patch distribution files...
1538 */
1539
1540 if (havepatchfiles)
1541 {
1542 if (Verbosity)
1543 puts("Creating non-shared software patch file...");
1544
1545 snprintf(pswname, sizeof(pswname), "%s.psw", prodfull);
1546 snprintf(filename, sizeof(filename), "%s/%s", directory, pswname);
1547
1548 unlink(filename);
1549 if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
1550 {
1551 fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n",
1552 filename, strerror(errno));
1553 return (1);
1554 }
1555
1556 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1557 if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
1558 switch (file->type)
1559 {
1560 case 'C' : /* Config file */
1561 case 'F' : /* Regular file */
1562 case 'I' : /* Init script */
1563 if (stat(file->src, &srcstat))
1564 {
1565 fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
1566 tar_close(tarfile);
1567 return (1);
1568 }
1569
1570 /*
1571 * Configuration files are extracted to the config file name with
1572 * .N appended; add a bit of script magic to check if the config
1573 * file already exists, and if not we copy the .N to the config
1574 * file location...
1575 */
1576
1577 if (file->type == 'C')
1578 snprintf(filename, sizeof(filename), "%s.N", file->dst);
1579 else if (file->type == 'I')
1580 snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir,
1581 file->dst);
1582 else
1583 strlcpy(filename, file->dst, sizeof(filename));
1584
1585 if (Verbosity > 1)
1586 printf("%s -> %s...\n", file->src, filename);
1587
1588 if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
1589 srcstat.st_mtime, file->user, file->group,
1590 filename, NULL) < 0)
1591 {
1592 tar_close(tarfile);
1593 return (1);
1594 }
1595
1596 if (tar_file(tarfile, file->src) < 0)
1597 {
1598 tar_close(tarfile);
1599 return (1);
1600 }
1601 break;
1602
1603 case 'd' : /* Create directory */
1604 if (Verbosity > 1)
1605 printf("%s...\n", file->dst);
1606 break;
1607
1608 case 'L' : /* Link file */
1609 if (Verbosity > 1)
1610 printf("%s -> %s...\n", file->src, file->dst);
1611
1612 if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
1613 file->user, file->group, file->dst, file->src) < 0)
1614 {
1615 tar_close(tarfile);
1616 return (1);
1617 }
1618 break;
1619 }
1620
1621 tar_close(tarfile);
1622
1623 if (Verbosity)
1624 puts("Creating shared software patch file...");
1625
1626 snprintf(pswname, sizeof(pswname), "%s.pss", prodfull);
1627 snprintf(filename, sizeof(filename), "%s/%s", directory, pswname);
1628
1629 unlink(filename);
1630 if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
1631 {
1632 fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n",
1633 filename, strerror(errno));
1634 return (1);
1635 }
1636
1637 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1638 if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
1639 switch (file->type)
1640 {
1641 case 'C' : /* Config file */
1642 case 'F' : /* Regular file */
1643 case 'I' : /* Init script */
1644 if (stat(file->src, &srcstat))
1645 {
1646 fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
1647 tar_close(tarfile);
1648 return (1);
1649 }
1650
1651 /*
1652 * Configuration files are extracted to the config file name with
1653 * .N appended; add a bit of script magic to check if the config
1654 * file already exists, and if not we copy the .N to the config
1655 * file location...
1656 */
1657
1658 if (file->type == 'C')
1659 snprintf(filename, sizeof(filename), "%s.N", file->dst);
1660 else if (file->type == 'I')
1661 snprintf(filename, sizeof(filename), "%s/init.d/%s",
1662 SoftwareDir, file->dst);
1663 else
1664 strlcpy(filename, file->dst, sizeof(filename));
1665
1666 if (Verbosity > 1)
1667 printf("%s -> %s...\n", file->src, filename);
1668
1669 if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
1670 srcstat.st_mtime, file->user, file->group,
1671 filename, NULL) < 0)
1672 {
1673 tar_close(tarfile);
1674 return (1);
1675 }
1676
1677 if (tar_file(tarfile, file->src) < 0)
1678 {
1679 tar_close(tarfile);
1680 return (1);
1681 }
1682 break;
1683
1684 case 'd' : /* Create directory */
1685 if (Verbosity > 1)
1686 printf("%s...\n", file->dst);
1687 break;
1688
1689 case 'L' : /* Link file */
1690 if (Verbosity > 1)
1691 printf("%s -> %s...\n", file->src, file->dst);
1692
1693 if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
1694 file->user, file->group, file->dst, file->src) < 0)
1695 {
1696 tar_close(tarfile);
1697 return (1);
1698 }
1699 break;
1700 }
1701
1702 tar_close(tarfile);
1703 }
1704
1705 /*
1706 * Create the scripts...
1707 */
1708
1709 if (write_install(dist, prodname, rootsize, usrsize, directory, subpackage))
1710 return (1);
1711
1712 if (havepatchfiles)
1713 if (write_patch(dist, prodname, prootsize, pusrsize, directory, subpackage))
1714 return (1);
1715
1716 if (write_remove(dist, prodname, rootsize, usrsize, directory, subpackage))
1717 return (1);
1718
1719 /*
1720 * Return...
1721 */
1722
1723 return (0);
1724 }
1725
1726
1727 /*
1728 * 'write_install()' - Write the installation script.
1729 */
1730
1731 static int /* O - -1 on error, 0 on success */
write_install(dist_t * dist,const char * prodname,int rootsize,int usrsize,const char * directory,const char * subpackage)1732 write_install(dist_t *dist, /* I - Software distribution */
1733 const char *prodname, /* I - Product name */
1734 int rootsize, /* I - Size of root files in kbytes */
1735 int usrsize, /* I - Size of /usr files in kbytes */
1736 const char *directory, /* I - Directory */
1737 const char *subpackage) /* I - Subpackage */
1738 {
1739 int i; /* Looping var */
1740 int col; /* Column in the output */
1741 FILE *scriptfile; /* Install script */
1742 char prodfull[255]; /* Full product name */
1743 char filename[1024]; /* Name of temporary file */
1744 file_t *file; /* Software file */
1745 const char *runlevels; /* Run levels */
1746 int number; /* Start/stop number */
1747
1748
1749 if (Verbosity)
1750 puts("Writing installation script...");
1751
1752 if (subpackage)
1753 snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
1754 else
1755 strlcpy(prodfull, prodname, sizeof(prodfull));
1756
1757 snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull);
1758
1759 if ((scriptfile = write_common(dist, "Installation", rootsize, usrsize,
1760 filename, subpackage)) == NULL)
1761 {
1762 fprintf(stderr, "epm: Unable to create installation script \"%s\" -\n"
1763 " %s\n", filename, strerror(errno));
1764 return (-1);
1765 }
1766
1767 fputs("if test \"$*\" = \"now\"; then\n", scriptfile);
1768 fputs(" echo Software license silently accepted via command-line option.\n", scriptfile);
1769 fputs("else\n", scriptfile);
1770 fputs(" echo \"\"\n", scriptfile);
1771 qprintf(scriptfile, " echo This installation script will install the %s\n",
1772 dist->product);
1773 qprintf(scriptfile, " echo software version %s on your system.\n",
1774 dist->version);
1775 fputs(" echo \"\"\n", scriptfile);
1776 fputs(" while true ; do\n", scriptfile);
1777 fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile);
1778 fputs(" read yesno\n", scriptfile);
1779 fputs(" case \"$yesno\" in\n", scriptfile);
1780 fputs(" y | yes | Y | Yes | YES)\n", scriptfile);
1781 fputs(" break\n", scriptfile);
1782 fputs(" ;;\n", scriptfile);
1783 fputs(" n | no | N | No | NO)\n", scriptfile);
1784 fputs(" exit 1\n", scriptfile);
1785 fputs(" ;;\n", scriptfile);
1786 fputs(" *)\n", scriptfile);
1787 fputs(" echo Please enter yes or no.\n", scriptfile);
1788 fputs(" ;;\n", scriptfile);
1789 fputs(" esac\n", scriptfile);
1790 fputs(" done\n", scriptfile);
1791
1792 if (dist->license[0])
1793 {
1794 fprintf(scriptfile, " more %s.license\n", prodfull);
1795 fputs(" echo \"\"\n", scriptfile);
1796 fputs(" while true ; do\n", scriptfile);
1797 fputs(" echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile);
1798 fputs(" read yesno\n", scriptfile);
1799 fputs(" case \"$yesno\" in\n", scriptfile);
1800 fputs(" y | yes | Y | Yes | YES)\n", scriptfile);
1801 fputs(" break\n", scriptfile);
1802 fputs(" ;;\n", scriptfile);
1803 fputs(" n | no | N | No | NO)\n", scriptfile);
1804 fputs(" exit 1\n", scriptfile);
1805 fputs(" ;;\n", scriptfile);
1806 fputs(" *)\n", scriptfile);
1807 fputs(" echo Please enter yes or no.\n", scriptfile);
1808 fputs(" ;;\n", scriptfile);
1809 fputs(" esac\n", scriptfile);
1810 fputs(" done\n", scriptfile);
1811 }
1812
1813 fputs("fi\n", scriptfile);
1814 fprintf(scriptfile, "if test -x %s/%s.remove; then\n", SoftwareDir, prodfull);
1815 fprintf(scriptfile, " echo Removing old versions of %s software...\n",
1816 prodfull);
1817 fprintf(scriptfile, " %s/%s.remove now\n", SoftwareDir, prodfull);
1818 fputs("fi\n", scriptfile);
1819
1820 write_space_checks(prodfull, scriptfile, rootsize ? "sw" : NULL,
1821 usrsize ? "ss" : NULL, rootsize, usrsize);
1822 write_depends(prodname, dist, scriptfile, subpackage);
1823 write_commands(dist, scriptfile, COMMAND_PRE_INSTALL, subpackage);
1824
1825 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1826 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
1827 strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
1828 break;
1829
1830 if (i)
1831 {
1832 fputs("echo Backing up old versions of non-shared files to be installed...\n", scriptfile);
1833
1834 col = fputs("for file in", scriptfile);
1835 for (; i > 0; i --, file ++)
1836 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
1837 strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
1838 {
1839 if (col > 80)
1840 col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
1841 else
1842 col += qprintf(scriptfile, " %s", file->dst);
1843 }
1844
1845 fputs("; do\n", scriptfile);
1846 fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile);
1847 fputs(" mv -f \"$file\" \"$file.O\"\n", scriptfile);
1848 fputs(" fi\n", scriptfile);
1849 fputs("done\n", scriptfile);
1850 }
1851
1852 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1853 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
1854 strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
1855 break;
1856
1857 if (i)
1858 {
1859 fputs("if test -w /usr ; then\n", scriptfile);
1860 fputs(" echo Backing up old versions of shared files to be installed...\n", scriptfile);
1861
1862 col = fputs(" for file in", scriptfile);
1863 for (; i > 0; i --, file ++)
1864 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
1865 strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
1866 {
1867 if (col > 80)
1868 col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
1869 else
1870 col += qprintf(scriptfile, " %s", file->dst);
1871 }
1872
1873 fputs("; do\n", scriptfile);
1874 fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile);
1875 fputs(" mv -f \"$file\" \"$file.O\"\n", scriptfile);
1876 fputs(" fi\n", scriptfile);
1877 fputs(" done\n", scriptfile);
1878 fputs("fi\n", scriptfile);
1879 }
1880
1881 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1882 if (tolower(file->type) == 'd' && file->subpackage == subpackage)
1883 break;
1884
1885 if (i)
1886 {
1887 fputs("echo Creating installation directories...\n", scriptfile);
1888
1889 for (; i > 0; i --, file ++)
1890 if (tolower(file->type) == 'd' && file->subpackage == subpackage)
1891 {
1892 qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n",
1893 file->dst, file->dst, file->dst);
1894 qprintf(scriptfile, " mkdir -p %s\n", file->dst);
1895 fputs("else\n", scriptfile);
1896 qprintf(scriptfile, " if test -f %s; then\n", file->dst);
1897 qprintf(scriptfile, " echo Error: %s already exists as a regular file!\n",
1898 file->dst);
1899 fputs(" exit 1\n", scriptfile);
1900 fputs(" fi\n", scriptfile);
1901 fputs("fi\n", scriptfile);
1902 qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
1903 qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
1904 qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst);
1905 }
1906 }
1907
1908 fputs("echo Installing software...\n", scriptfile);
1909
1910 if (rootsize)
1911 {
1912 if (CompressFiles)
1913 fprintf(scriptfile, "gzip -dc %s.sw | $ac_tar -\n", prodfull);
1914 else
1915 fprintf(scriptfile, "$ac_tar %s.sw\n", prodfull);
1916 }
1917
1918 if (usrsize)
1919 {
1920 fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile);
1921 if (CompressFiles)
1922 fprintf(scriptfile, " gzip -dc %s.ss | $ac_tar -\n", prodfull);
1923 else
1924 fprintf(scriptfile, " $ac_tar %s.ss\n", prodfull);
1925 fputs("fi\n", scriptfile);
1926 }
1927
1928 fprintf(scriptfile, "if test -d %s; then\n", SoftwareDir);
1929 fprintf(scriptfile, " rm -f %s/%s.remove\n", SoftwareDir, prodfull);
1930 fputs("else\n", scriptfile);
1931 fprintf(scriptfile, " mkdir -p %s\n", SoftwareDir);
1932 fputs("fi\n", scriptfile);
1933 fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir);
1934 fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull);
1935
1936 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1937 if (tolower(file->type) == 'c' && file->subpackage == subpackage)
1938 break;
1939
1940 if (i)
1941 {
1942 fputs("echo Checking configuration files...\n", scriptfile);
1943
1944 col = fputs("for file in", scriptfile);
1945 for (; i > 0; i --, file ++)
1946 if (tolower(file->type) == 'c' && file->subpackage == subpackage)
1947 {
1948 if (col > 80)
1949 col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
1950 else
1951 col += qprintf(scriptfile, " %s", file->dst);
1952 }
1953
1954 fputs("; do\n", scriptfile);
1955 fputs(" if test ! -f \"$file\"; then\n", scriptfile);
1956 fputs(" cp \"$file.N\" \"$file\"\n", scriptfile);
1957 fputs(" fi\n", scriptfile);
1958 fputs("done\n", scriptfile);
1959 }
1960
1961 fputs("echo Updating file permissions...\n", scriptfile);
1962
1963 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1964 if (strncmp(file->dst, "/usr", 4) != 0 &&
1965 strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
1966 switch (tolower(file->type))
1967 {
1968 case 'c' :
1969 qprintf(scriptfile, "chown %s %s.N\n", file->user, file->dst);
1970 qprintf(scriptfile, "chgrp %s %s.N\n", file->group, file->dst);
1971 case 'f' :
1972 qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
1973 qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
1974 break;
1975 }
1976
1977 fputs("if test -f /usr/.writetest; then\n", scriptfile);
1978 fputs(" rm -f /usr/.writetest\n", scriptfile);
1979 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1980 if (strncmp(file->dst, "/usr", 4) == 0 &&
1981 strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
1982 switch (tolower(file->type))
1983 {
1984 case 'c' :
1985 qprintf(scriptfile, " chown %s %s.N\n", file->user, file->dst);
1986 qprintf(scriptfile, " chgrp %s %s.N\n", file->group, file->dst);
1987 case 'f' :
1988 qprintf(scriptfile, " chown %s %s\n", file->user, file->dst);
1989 qprintf(scriptfile, " chgrp %s %s\n", file->group, file->dst);
1990 break;
1991 }
1992 fputs("fi\n", scriptfile);
1993
1994 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
1995 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
1996 break;
1997
1998 if (i)
1999 {
2000 fputs("echo Setting up init scripts...\n", scriptfile);
2001
2002 /*
2003 * Find where the frigging init scripts go...
2004 */
2005
2006 fputs("rcdir=\"\"\n", scriptfile);
2007 fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile);
2008 fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o "
2009 "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile);
2010 fputs(" rcdir=\"$dir\"\n", scriptfile);
2011 fputs(" fi\n", scriptfile);
2012 fputs("done\n", scriptfile);
2013 fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile);
2014 fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile);
2015 fputs(" for file in", scriptfile);
2016 for (; i > 0; i --, file ++)
2017 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2018 qprintf(scriptfile, " %s", file->dst);
2019 fputs("; do\n", scriptfile);
2020 fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile);
2021 qprintf(scriptfile, " ln -s %s/init.d/$file "
2022 "/usr/local/etc/rc.d/$file.sh\n",
2023 SoftwareDir);
2024 fputs(" done\n", scriptfile);
2025 fputs(" else\n", scriptfile);
2026 fputs(" echo Unable to determine location of startup scripts!\n", scriptfile);
2027 fputs(" fi\n", scriptfile);
2028 fputs("else\n", scriptfile);
2029 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2030 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2031 {
2032 fputs(" if test -d $rcdir/init.d; then\n", scriptfile);
2033 qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst);
2034 qprintf(scriptfile, " /bin/ln -s %s/init.d/%s "
2035 "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst);
2036 fputs(" else\n", scriptfile);
2037 fputs(" if test -d /etc/init.d; then\n", scriptfile);
2038 qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst);
2039 qprintf(scriptfile, " /bin/ln -s %s/init.d/%s "
2040 "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst);
2041 fputs(" fi\n", scriptfile);
2042 fputs(" fi\n", scriptfile);
2043
2044 for (runlevels = get_runlevels(dist->files + i, "0235");
2045 isdigit(*runlevels & 255);
2046 runlevels ++)
2047 {
2048 if (*runlevels == '0')
2049 number = get_stop(file, 0);
2050 else
2051 number = get_start(file, 99);
2052
2053 fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels);
2054 qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n",
2055 *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst);
2056 qprintf(scriptfile, " /bin/ln -s %s/init.d/%s "
2057 "$rcdir/rc%c.d/%c%02d%s\n",
2058 SoftwareDir, file->dst, *runlevels,
2059 *runlevels == '0' ? 'K' : 'S', number, file->dst);
2060 fputs(" fi\n", scriptfile);
2061 }
2062
2063 #ifdef __sgi
2064 fputs(" if test -x /etc/chkconfig; then\n", scriptfile);
2065 qprintf(scriptfile, " /etc/chkconfig -f %s on\n", file->dst);
2066 fputs(" fi\n", scriptfile);
2067 #endif /* __sgi */
2068
2069 }
2070
2071 fputs("fi\n", scriptfile);
2072 }
2073
2074 write_commands(dist, scriptfile, COMMAND_POST_INSTALL, subpackage);
2075
2076 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2077 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2078 qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst);
2079
2080 fputs("echo Installation is complete.\n", scriptfile);
2081
2082 fclose(scriptfile);
2083
2084 return (0);
2085 }
2086
2087
2088 /*
2089 * 'write_instfiles()' - Write the installer files to the tar file...
2090 */
2091
2092 static int /* O - 0 = success, -1 on failure */
write_instfiles(tarf_t * tarfile,const char * directory,const char * prodname,const char * platname,const char ** files,const char * destdir,const char * subpackage)2093 write_instfiles(tarf_t *tarfile, /* I - Distribution tar file */
2094 const char *directory, /* I - Output directory */
2095 const char *prodname, /* I - Base product name */
2096 const char *platname, /* I - Platform name */
2097 const char **files, /* I - Files */
2098 const char *destdir, /* I - Destination directory in tar file */
2099 const char *subpackage) /* I - Subpackage */
2100 {
2101 int i; /* Looping var */
2102 char srcname[1024], /* Name of source file in distribution */
2103 dstname[1024], /* Name of destination file in distribution */
2104 prodfull[255]; /* Full name of product */
2105 struct stat srcstat; /* Source file information */
2106
2107
2108 if (subpackage)
2109 snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
2110 else
2111 strlcpy(prodfull, prodname, sizeof(prodfull));
2112
2113 for (i = 0; files[i] != NULL; i ++)
2114 {
2115 snprintf(srcname, sizeof(srcname), "%s/%s.%s", directory, prodfull, files[i]);
2116 snprintf(dstname, sizeof(dstname), "%s%s.%s", destdir, prodfull, files[i]);
2117
2118 if (stat(srcname, &srcstat))
2119 {
2120 if (!i)
2121 break;
2122 else
2123 continue;
2124 }
2125
2126 if (srcstat.st_size == 0)
2127 continue;
2128
2129 if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & 07555,
2130 srcstat.st_size, srcstat.st_mtime, "root", "root",
2131 dstname, NULL) < 0)
2132 {
2133 return (-1);
2134 }
2135
2136 if (tar_file(tarfile, srcname) < 0)
2137 return (-1);
2138
2139 if (Verbosity)
2140 printf(" %7.0fk %s.%s\n", (srcstat.st_size + 1023) / 1024.0,
2141 prodfull, files[i]);
2142 }
2143
2144 return (0);
2145 }
2146
2147
2148 /*
2149 * 'write_patch()' - Write the patch script.
2150 */
2151
2152 static int /* O - -1 on error, 0 on success */
write_patch(dist_t * dist,const char * prodname,int rootsize,int usrsize,const char * directory,const char * subpackage)2153 write_patch(dist_t *dist, /* I - Software distribution */
2154 const char *prodname, /* I - Product name */
2155 int rootsize, /* I - Size of root files in kbytes */
2156 int usrsize, /* I - Size of /usr files in kbytes */
2157 const char *directory, /* I - Directory */
2158 const char *subpackage) /* I - Subpackage */
2159 {
2160 int i; /* Looping var */
2161 FILE *scriptfile; /* Patch script */
2162 char filename[1024]; /* Name of temporary file */
2163 char prodfull[255]; /* Full product name */
2164 file_t *file; /* Software file */
2165 const char *runlevels; /* Run levels */
2166 int number; /* Start/stop number */
2167
2168
2169 if (Verbosity)
2170 puts("Writing patch script...");
2171
2172 if (subpackage)
2173 snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
2174 else
2175 strlcpy(prodfull, prodname, sizeof(prodfull));
2176
2177 snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull);
2178
2179 if ((scriptfile = write_common(dist, "Patch", rootsize, usrsize,
2180 filename, subpackage)) == NULL)
2181 {
2182 fprintf(stderr, "epm: Unable to create patch script \"%s\" -\n"
2183 " %s\n", filename, strerror(errno));
2184 return (-1);
2185 }
2186
2187 fputs("if test \"$*\" = \"now\"; then\n", scriptfile);
2188 fputs(" echo Software license silently accepted via command-line option.\n", scriptfile);
2189 fputs("else\n", scriptfile);
2190 fputs(" echo \"\"\n", scriptfile);
2191 qprintf(scriptfile, " echo This installation script will patch the %s\n",
2192 dist->product);
2193 qprintf(scriptfile, " echo software to version %s on your system.\n", dist->version);
2194 fputs(" echo \"\"\n", scriptfile);
2195 fputs(" while true ; do\n", scriptfile);
2196 fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile);
2197 fputs(" read yesno\n", scriptfile);
2198 fputs(" case \"$yesno\" in\n", scriptfile);
2199 fputs(" y | yes | Y | Yes | YES)\n", scriptfile);
2200 fputs(" break\n", scriptfile);
2201 fputs(" ;;\n", scriptfile);
2202 fputs(" n | no | N | No | NO)\n", scriptfile);
2203 fputs(" exit 1\n", scriptfile);
2204 fputs(" ;;\n", scriptfile);
2205 fputs(" *)\n", scriptfile);
2206 fputs(" echo Please enter yes or no.\n", scriptfile);
2207 fputs(" ;;\n", scriptfile);
2208 fputs(" esac\n", scriptfile);
2209 fputs(" done\n", scriptfile);
2210
2211 if (dist->license[0])
2212 {
2213 fprintf(scriptfile, " more %s.license\n", prodfull);
2214 fputs(" echo \"\"\n", scriptfile);
2215 fputs(" while true ; do\n", scriptfile);
2216 fputs(" echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile);
2217 fputs(" read yesno\n", scriptfile);
2218 fputs(" case \"$yesno\" in\n", scriptfile);
2219 fputs(" y | yes | Y | Yes | YES)\n", scriptfile);
2220 fputs(" break\n", scriptfile);
2221 fputs(" ;;\n", scriptfile);
2222 fputs(" n | no | N | No | NO)\n", scriptfile);
2223 fputs(" exit 1\n", scriptfile);
2224 fputs(" ;;\n", scriptfile);
2225 fputs(" *)\n", scriptfile);
2226 fputs(" echo Please enter yes or no.\n", scriptfile);
2227 fputs(" ;;\n", scriptfile);
2228 fputs(" esac\n", scriptfile);
2229 fputs(" done\n", scriptfile);
2230 }
2231
2232 fputs("fi\n", scriptfile);
2233
2234 write_space_checks(prodfull, scriptfile, rootsize ? "psw" : NULL,
2235 usrsize ? "pss" : NULL, rootsize, usrsize);
2236 write_depends(prodname, dist, scriptfile, subpackage);
2237
2238 fprintf(scriptfile, "if test ! -x %s/%s.remove; then\n",
2239 SoftwareDir, prodfull);
2240 fputs(" echo You do not appear to have the base software installed!\n",
2241 scriptfile);
2242 fputs(" echo Please install the full distribution instead.\n", scriptfile);
2243 fputs(" exit 1\n", scriptfile);
2244 fputs("fi\n", scriptfile);
2245
2246 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2247 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2248 qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst);
2249
2250 write_commands(dist, scriptfile, COMMAND_PRE_PATCH, subpackage);
2251
2252 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2253 if (file->type == 'D' && file->subpackage == subpackage)
2254 break;
2255
2256 if (i)
2257 {
2258 fputs("echo Creating new installation directories...\n", scriptfile);
2259
2260 for (; i > 0; i --, file ++)
2261 if (file->type == 'D' && file->subpackage == subpackage)
2262 {
2263 qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n",
2264 file->dst, file->dst, file->dst);
2265 qprintf(scriptfile, " mkdir -p %s\n", file->dst);
2266 fputs("else\n", scriptfile);
2267 qprintf(scriptfile, " if test -f %s; then\n", file->dst);
2268 qprintf(scriptfile, " echo Error: %s already exists as a regular file!\n",
2269 file->dst);
2270 fputs(" exit 1\n", scriptfile);
2271 fputs(" fi\n", scriptfile);
2272 fputs("fi\n", scriptfile);
2273 qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
2274 qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
2275 qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst);
2276 }
2277 }
2278
2279 fputs("echo Patching software...\n", scriptfile);
2280
2281 if (rootsize)
2282 {
2283 if (CompressFiles)
2284 fprintf(scriptfile, "gzip -dc %s.psw | $ac_tar -\n", prodfull);
2285 else
2286 fprintf(scriptfile, "$ac_tar %s.psw\n", prodfull);
2287 }
2288
2289 if (usrsize)
2290 {
2291 fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile);
2292 if (CompressFiles)
2293 fprintf(scriptfile, " gzip -dc %s.pss | $ac_tar -\n", prodfull);
2294 else
2295 fprintf(scriptfile, " $ac_tar %s.pss\n", prodfull);
2296 fputs("fi\n", scriptfile);
2297 }
2298
2299 fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull);
2300 fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir);
2301 fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull);
2302
2303 fputs("echo Updating file permissions...\n", scriptfile);
2304
2305 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2306 if (strncmp(file->dst, "/usr", 4) != 0 &&
2307 strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
2308 switch (file->type)
2309 {
2310 case 'C' :
2311 case 'F' :
2312 qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
2313 qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
2314 break;
2315 }
2316
2317 fputs("if test -f /usr/.writetest; then\n", scriptfile);
2318 fputs(" rm -f /usr/.writetest\n", scriptfile);
2319 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2320 if (strncmp(file->dst, "/usr", 4) == 0 &&
2321 strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
2322 switch (file->type)
2323 {
2324 case 'C' :
2325 case 'F' :
2326 qprintf(scriptfile, " chown %s %s\n", file->user, file->dst);
2327 qprintf(scriptfile, " chgrp %s %s\n", file->group, file->dst);
2328 break;
2329 }
2330 fputs("fi\n", scriptfile);
2331
2332 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2333 if (file->type == 'C' && file->subpackage == subpackage)
2334 break;
2335
2336 if (i)
2337 {
2338 fputs("echo Checking configuration files...\n", scriptfile);
2339
2340 fputs("for file in", scriptfile);
2341 for (; i > 0; i --, file ++)
2342 if (file->type == 'C' && file->subpackage == subpackage)
2343 qprintf(scriptfile, " %s", file->dst);
2344
2345 fputs("; do\n", scriptfile);
2346 fputs(" if test ! -f \"$file\"; then\n", scriptfile);
2347 fputs(" cp \"$file.N\" \"$file\"\n", scriptfile);
2348 fputs(" fi\n", scriptfile);
2349 fputs("done\n", scriptfile);
2350 }
2351
2352 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2353 if (file->type == 'R' && file->subpackage == subpackage)
2354 break;
2355
2356 if (i)
2357 {
2358 fputs("echo Removing files that are no longer used...\n", scriptfile);
2359
2360 fputs("for file in", scriptfile);
2361 for (; i > 0; i --, file ++)
2362 if (file->type == 'R' && file->subpackage == subpackage)
2363 qprintf(scriptfile, " %s", file->dst);
2364
2365 fputs("; do\n", scriptfile);
2366 fputs(" rm -f \"$file\"\n", scriptfile);
2367 fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile);
2368 fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile);
2369 fputs(" fi\n", scriptfile);
2370 fputs("done\n", scriptfile);
2371 }
2372
2373 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2374 if (file->type == 'I' && file->subpackage == subpackage)
2375 break;
2376
2377 if (i)
2378 {
2379 fputs("echo Setting up init scripts...\n", scriptfile);
2380
2381 /*
2382 * Find where the frigging init scripts go...
2383 */
2384
2385 fputs("rcdir=\"\"\n", scriptfile);
2386 fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile);
2387 fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o "
2388 "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile);
2389 fputs(" rcdir=\"$dir\"\n", scriptfile);
2390 fputs(" fi\n", scriptfile);
2391 fputs("done\n", scriptfile);
2392 fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile);
2393 fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile);
2394 fputs(" for file in", scriptfile);
2395 for (; i > 0; i --, file ++)
2396 if (tolower(file->type) == 'I' && file->subpackage == subpackage)
2397 qprintf(scriptfile, " %s", file->dst);
2398 fputs("; do\n", scriptfile);
2399 fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile);
2400 qprintf(scriptfile, " ln -s %s/init.d/$file "
2401 "/usr/local/etc/rc.d/$file.sh\n",
2402 SoftwareDir);
2403 fputs(" done\n", scriptfile);
2404 fputs(" else\n", scriptfile);
2405 fputs(" echo Unable to determine location of startup scripts!\n", scriptfile);
2406 fputs(" fi\n", scriptfile);
2407 fputs("else\n", scriptfile);
2408 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2409 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2410 {
2411 fputs(" if test -d $rcdir/init.d; then\n", scriptfile);
2412 qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst);
2413 qprintf(scriptfile, " /bin/ln -s %s/init.d/%s "
2414 "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst);
2415 fputs(" else\n", scriptfile);
2416 fputs(" if test -d /etc/init.d; then\n", scriptfile);
2417 qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst);
2418 qprintf(scriptfile, " /bin/ln -s %s/init.d/%s "
2419 "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst);
2420 fputs(" fi\n", scriptfile);
2421 fputs(" fi\n", scriptfile);
2422
2423 for (runlevels = get_runlevels(dist->files + i, "0235");
2424 isdigit(*runlevels & 255);
2425 runlevels ++)
2426 {
2427 if (*runlevels == '0')
2428 number = get_stop(file, 0);
2429 else
2430 number = get_start(file, 99);
2431
2432 fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels);
2433 qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n",
2434 *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst);
2435 qprintf(scriptfile, " /bin/ln -s %s/init.d/%s "
2436 "$rcdir/rc%c.d/%c%02d%s\n",
2437 SoftwareDir, file->dst, *runlevels,
2438 *runlevels == '0' ? 'K' : 'S', number, file->dst);
2439 fputs(" fi\n", scriptfile);
2440 }
2441
2442 #ifdef __sgi
2443 fputs(" if test -x /etc/chkconfig; then\n", scriptfile);
2444 qprintf(scriptfile, " /etc/chkconfig -f %s on\n", file->dst);
2445 fputs(" fi\n", scriptfile);
2446 #endif /* __sgi */
2447 }
2448
2449 fputs("fi\n", scriptfile);
2450 }
2451
2452 write_commands(dist, scriptfile, COMMAND_POST_PATCH, subpackage);
2453
2454 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2455 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2456 qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst);
2457
2458 fputs("echo Patching is complete.\n", scriptfile);
2459
2460 fclose(scriptfile);
2461
2462 return (0);
2463 }
2464
2465
2466 /*
2467 * 'write_remove()' - Write the removal script.
2468 */
2469
2470 static int /* O - -1 on error, 0 on success */
write_remove(dist_t * dist,const char * prodname,int rootsize,int usrsize,const char * directory,const char * subpackage)2471 write_remove(dist_t *dist, /* I - Software distribution */
2472 const char *prodname, /* I - Product name */
2473 int rootsize, /* I - Size of root files in kbytes */
2474 int usrsize, /* I - Size of /usr files in kbytes */
2475 const char *directory, /* I - Directory */
2476 const char *subpackage) /* I - Subpackage */
2477 {
2478 int i; /* Looping var */
2479 int col; /* Current column */
2480 FILE *scriptfile; /* Remove script */
2481 char filename[1024]; /* Name of temporary file */
2482 char prodfull[255]; /* Full product name */
2483 file_t *file; /* Software file */
2484 const char *runlevels; /* Run levels */
2485 int number; /* Start/stop number */
2486
2487
2488 if (Verbosity)
2489 puts("Writing removal script...");
2490
2491 if (subpackage)
2492 snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
2493 else
2494 strlcpy(prodfull, prodname, sizeof(prodfull));
2495
2496 snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull);
2497
2498 if ((scriptfile = write_common(dist, "Removal", rootsize, usrsize,
2499 filename, subpackage)) == NULL)
2500 {
2501 fprintf(stderr, "epm: Unable to create removal script \"%s\" -\n"
2502 " %s\n", filename, strerror(errno));
2503 return (-1);
2504 }
2505
2506 fputs("if test ! \"$*\" = \"now\"; then\n", scriptfile);
2507 fputs(" echo \"\"\n", scriptfile);
2508 qprintf(scriptfile, " echo This removal script will remove the %s\n",
2509 dist->product);
2510 qprintf(scriptfile, " echo software version %s from your system.\n",
2511 dist->version);
2512 fputs(" echo \"\"\n", scriptfile);
2513 fputs(" while true ; do\n", scriptfile);
2514 fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile);
2515 fputs(" read yesno\n", scriptfile);
2516 fputs(" case \"$yesno\" in\n", scriptfile);
2517 fputs(" y | yes | Y | Yes | YES)\n", scriptfile);
2518 fputs(" break\n", scriptfile);
2519 fputs(" ;;\n", scriptfile);
2520 fputs(" n | no | N | No | NO)\n", scriptfile);
2521 fputs(" exit 1\n", scriptfile);
2522 fputs(" ;;\n", scriptfile);
2523 fputs(" *)\n", scriptfile);
2524 fputs(" echo Please enter yes or no.\n", scriptfile);
2525 fputs(" ;;\n", scriptfile);
2526 fputs(" esac\n", scriptfile);
2527 fputs(" done\n", scriptfile);
2528 fputs("fi\n", scriptfile);
2529
2530 /*
2531 * Find any removal commands in the list file...
2532 */
2533
2534 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2535 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2536 qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst);
2537
2538 write_commands(dist, scriptfile, COMMAND_PRE_REMOVE, subpackage);
2539
2540 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2541 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2542 break;
2543
2544 if (i)
2545 {
2546 fputs("echo Cleaning up init scripts...\n", scriptfile);
2547
2548 /*
2549 * Find where the frigging init scripts go...
2550 */
2551
2552 fputs("rcdir=\"\"\n", scriptfile);
2553 fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile);
2554 fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o "
2555 "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile);
2556 fputs(" rcdir=\"$dir\"\n", scriptfile);
2557 fputs(" fi\n", scriptfile);
2558 fputs("done\n", scriptfile);
2559 fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile);
2560 fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile);
2561 fputs(" for file in", scriptfile);
2562 for (; i > 0; i --, file ++)
2563 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2564 qprintf(scriptfile, " %s", file->dst);
2565 fputs("; do\n", scriptfile);
2566 fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile);
2567 fputs(" done\n", scriptfile);
2568 fputs(" else\n", scriptfile);
2569 fputs(" echo Unable to determine location of startup scripts!\n", scriptfile);
2570 fputs(" fi\n", scriptfile);
2571 fputs("else\n", scriptfile);
2572 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2573 if (tolower(file->type) == 'i' && file->subpackage == subpackage)
2574 {
2575 qprintf(scriptfile, " %s/init.d/%s stop\n", SoftwareDir, file->dst);
2576
2577 fputs(" if test -d $rcdir/init.d; then\n", scriptfile);
2578 qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst);
2579 fputs(" else\n", scriptfile);
2580 fputs(" if test -d /etc/init.d; then\n", scriptfile);
2581 qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst);
2582 fputs(" fi\n", scriptfile);
2583 fputs(" fi\n", scriptfile);
2584
2585 for (runlevels = get_runlevels(dist->files + i, "0235");
2586 isdigit(*runlevels & 255);
2587 runlevels ++)
2588 {
2589 if (*runlevels == '0')
2590 number = get_stop(file, 0);
2591 else
2592 number = get_start(file, 99);
2593
2594 fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels);
2595 qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n",
2596 *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst);
2597 fputs(" fi\n", scriptfile);
2598 }
2599
2600 #ifdef __sgi
2601 fputs(" if test -x /etc/chkconfig; then\n", scriptfile);
2602 qprintf(scriptfile, " rm -f /etc/config/%s\n", file->dst);
2603 fputs(" fi\n", scriptfile);
2604 #endif /* __sgi */
2605 }
2606
2607 fputs("fi\n", scriptfile);
2608 }
2609
2610 fputs("echo Removing/restoring installed files...\n", scriptfile);
2611
2612 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2613 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
2614 strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
2615 break;
2616
2617 if (i)
2618 {
2619 col = fputs("for file in", scriptfile);
2620 for (; i > 0; i --, file ++)
2621 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
2622 strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
2623 {
2624 if (col > 80)
2625 col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
2626 else
2627 col += qprintf(scriptfile, " %s", file->dst);
2628 }
2629
2630 fputs("; do\n", scriptfile);
2631 fputs(" rm -f \"$file\"\n", scriptfile);
2632 fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile);
2633 fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile);
2634 fputs(" fi\n", scriptfile);
2635 fputs("done\n", scriptfile);
2636 }
2637
2638 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2639 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
2640 strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
2641 break;
2642
2643 if (i)
2644 {
2645 fputs("if test -w /usr ; then\n", scriptfile);
2646 col = fputs(" for file in", scriptfile);
2647 for (; i > 0; i --, file ++)
2648 if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
2649 strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
2650 {
2651 if (col > 80)
2652 col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
2653 else
2654 col += qprintf(scriptfile, " %s", file->dst);
2655 }
2656
2657 fputs("; do\n", scriptfile);
2658 fputs(" rm -f \"$file\"\n", scriptfile);
2659 fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile);
2660 fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile);
2661 fputs(" fi\n", scriptfile);
2662 fputs(" done\n", scriptfile);
2663 fputs("fi\n", scriptfile);
2664 }
2665
2666 fputs("echo Checking configuration files...\n", scriptfile);
2667
2668 for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
2669 if (tolower(file->type) == 'c' && file->subpackage == subpackage)
2670 break;
2671
2672 if (i)
2673 {
2674 col = fputs("for file in", scriptfile);
2675 for (; i > 0; i --, file ++)
2676 if (tolower(file->type) == 'c' && file->subpackage == subpackage)
2677 {
2678 if (col > 80)
2679 col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
2680 else
2681 col += qprintf(scriptfile, " %s", file->dst);
2682 }
2683
2684 fputs("; do\n", scriptfile);
2685 fputs(" if cmp -s \"$file\" \"$file.N\"; then\n", scriptfile);
2686 fputs(" # Config file not changed\n", scriptfile);
2687 fputs(" rm -f \"$file\"\n", scriptfile);
2688 fputs(" fi\n", scriptfile);
2689 fputs(" rm -f \"$file.N\"\n", scriptfile);
2690 fputs("done\n", scriptfile);
2691 }
2692
2693 for (i = dist->num_files, file = dist->files + i - 1; i > 0; i --, file --)
2694 if (tolower(file->type) == 'd' && file->subpackage == subpackage)
2695 break;
2696
2697 if (i)
2698 {
2699 fputs("echo Removing empty installation directories...\n", scriptfile);
2700
2701 for (; i > 0; i --, file --)
2702 if (tolower(file->type) == 'd' && file->subpackage == subpackage)
2703 {
2704 qprintf(scriptfile, "if test -d %s; then\n", file->dst);
2705 qprintf(scriptfile, " rmdir %s >/dev/null 2>&1\n", file->dst);
2706 fputs("fi\n", scriptfile);
2707 }
2708 }
2709
2710 write_commands(dist, scriptfile, COMMAND_POST_REMOVE, subpackage);
2711
2712 fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull);
2713
2714 fputs("echo Removal is complete.\n", scriptfile);
2715
2716 fclose(scriptfile);
2717
2718 return (0);
2719 }
2720
2721
2722 /*
2723 * 'write_space_checks()' - Write disk space checks for the installer.
2724 */
2725
2726 static int /* O - 0 on success, -1 on error */
write_space_checks(const char * prodname,FILE * fp,const char * sw,const char * ss,int rootsize,int usrsize)2727 write_space_checks(const char *prodname,/* I - Distribution name */
2728 FILE *fp, /* I - File to write to */
2729 const char *sw, /* I - / archive */
2730 const char *ss, /* I - /usr archive */
2731 int rootsize, /* I - / install size in kbytes */
2732 int usrsize) /* I - /usr install size in kbytes */
2733 {
2734 fputs("case `uname` in\n", fp);
2735 fputs(" AIX)\n", fp);
2736 fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp);
2737 fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
2738 fputs(" fsroot=`echo $dfroot | awk '{print $15}'`\n", fp);
2739 fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp);
2740 fputs(" fsusr=`echo $dfusr | awk '{print $15}'`\n", fp);
2741 fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp);
2742 fputs(" ;;\n\n", fp);
2743 fputs(" HP-UX)\n", fp);
2744 fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp);
2745 fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
2746 fputs(" fsroot=`echo $dfroot | awk '{print $1}'`\n", fp);
2747 fputs(" sproot=`echo $dfroot | awk '{print $9}'`\n", fp);
2748 fputs(" fsusr=`echo $dfusr | awk '{print $1}'`\n", fp);
2749 fputs(" spusr=`echo $dfusr | awk '{print $9}'`\n", fp);
2750 fputs(" ;;\n\n", fp);
2751 fputs(" IRIX*)\n", fp);
2752 fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp);
2753 fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
2754 fputs(" fsroot=`echo $dfroot | awk '{print $15}'`\n", fp);
2755 fputs(" sproot=`echo $dfroot | awk '{print $13}'`\n", fp);
2756 fputs(" fsusr=`echo $dfusr | awk '{print $15}'`\n", fp);
2757 fputs(" spusr=`echo $dfusr | awk '{print $13}'`\n", fp);
2758 fputs(" ;;\n\n", fp);
2759 fputs(" SCO*)\n", fp);
2760 fputs(" dfroot=`df -k -B / | tr '\\n' ' '`\n", fp);
2761 fputs(" dfusr=`df -k -B /usr | tr '\\n' ' '`\n", fp);
2762 fputs(" fsroot=`echo $dfroot | awk '{print $13}'`\n", fp);
2763 fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp);
2764 fputs(" fsusr=`echo $dfusr | awk '{print $13}'`\n", fp);
2765 fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp);
2766 fputs(" ;;\n\n", fp);
2767 fputs(" *)\n", fp);
2768 fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp);
2769 fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
2770 fputs(" fsroot=`echo $dfroot | awk '{print $13}'`\n", fp);
2771 fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp);
2772 fputs(" fsusr=`echo $dfusr | awk '{print $13}'`\n", fp);
2773 fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp);
2774 fputs(" ;;\n", fp);
2775 fputs("esac\n", fp);
2776 fputs("\n", fp);
2777
2778 fputs("if test x$sproot = x -o x$spusr = x; then\n", fp);
2779 fputs(" echo WARNING: Unable to determine available disk space\\; "
2780 "installing blindly...\n", fp);
2781 fputs("else\n", fp);
2782 fputs(" if test x$fsroot = x$fsusr; then\n", fp);
2783 fprintf(fp, " if test %d -gt $sproot; then\n", rootsize + usrsize);
2784 fputs(" echo Not enough free disk space for "
2785 "software:\n", fp);
2786 fprintf(fp, " echo You need %d kbytes but only have "
2787 "$sproot kbytes available.\n", rootsize + usrsize);
2788 fputs(" exit 1\n", fp);
2789 fputs(" fi\n", fp);
2790 fputs(" else\n", fp);
2791 fprintf(fp, " if test %d -gt $sproot; then\n", rootsize);
2792 fputs(" echo Not enough free disk space for "
2793 "software:\n", fp);
2794 fprintf(fp, " echo You need %d kbytes in / but only have "
2795 "$sproot kbytes available.\n", rootsize);
2796 fputs(" exit 1\n", fp);
2797 fputs(" fi\n", fp);
2798 fputs("\n", fp);
2799 fprintf(fp, " if test %d -gt $spusr; then\n", usrsize);
2800 fputs(" echo Not enough free disk space for "
2801 "software:\n", fp);
2802 fprintf(fp, " echo You need %d kbytes in /usr but only have "
2803 "$spusr kbytes available.\n", usrsize);
2804 fputs(" exit 1\n", fp);
2805 fputs(" fi\n", fp);
2806 fputs(" fi\n", fp);
2807 fputs("fi\n", fp);
2808
2809 return (0);
2810 }
2811