source: trunk/emx/src/emxupd/emxupd.c@ 3669

Last change on this file since 3669 was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 3.9 KB
Line 
1/* emxupd.c -- Update a DLL or EXE which is in use
2 Copyright (c) 1996 Eberhard Mattes
3
4This file is part of emxupd.
5
6emxupd is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11emxupd is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with emxupd; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#define INCL_DOSERRORS
23#define INCL_DOSFILEMGR
24#include <stdio.h>
25#include <stdlib.h>
26#include <getopt.h>
27#include <os2.h>
28
29APIRET APIENTRY DosReplaceModule (PCSZ pszOld, PCSZ pszNew, PCSZ pszBackup);
30
31
32static void usage (void)
33{
34 puts ("Usage: emxupd <source_file> <target_path>\n"
35 " emxupd -d <old_file>\n"
36 "Options:\n"
37 " -d Delete the file");
38 exit (1);
39}
40
41
42static void replace_module (const char *old_path, const char *new_path)
43{
44 ULONG rc;
45
46 /* First try to delete or copy the file the standard way. Note that
47 DosReplaceModule works only if the file is really in use. */
48
49 if (new_path == NULL)
50 rc = DosDelete (old_path);
51 else
52 rc = DosCopy (new_path, old_path, DCPY_EXISTING | DCPY_FAILEAS);
53
54 /* If deleting or copying the file failed due to the module being in
55 use, call DosReplaceModule. */
56
57 if (rc == ERROR_SHARING_VIOLATION)
58 {
59 rc = DosReplaceModule (old_path, new_path, NULL);
60 if (rc == 0 && new_path == NULL)
61 rc = DosDelete (old_path);
62 }
63
64 /* Examine the return code. */
65
66 switch (rc)
67 {
68 case 0:
69 return;
70 case ERROR_FILE_NOT_FOUND:
71 puts ("File not found.");
72 exit (2);
73 case ERROR_PATH_NOT_FOUND:
74 puts ("Path not found.");
75 exit (2);
76 case ERROR_MODULE_IN_USE:
77 puts ("Module is in use.");
78 exit (2);
79 default:
80 printf ("Operation failed, error code = %lu.\n", rc);
81 exit (2);
82 }
83}
84
85
86#define PATH_DELIM_P(c) ((c) == ':' || (c) == '\\' || (c) == '/')
87
88static void update (const char *source_path, const char *target_path)
89{
90 ULONG rc;
91 FILESTATUS3 info;
92 size_t len;
93 const char *last;
94 char concat[CCHMAXPATH];
95
96 /* If TARGET_PATH is a directory, append the last component of
97 SOURCE_PATH to TARGET_PATH. */
98
99 rc = DosQueryPathInfo (target_path, FIL_STANDARD, &info, sizeof (info));
100 if (rc == 0 && (info.attrFile & FILE_DIRECTORY))
101 {
102 len = strlen (target_path);
103 last = _getname (source_path);
104 if (len != 0 && PATH_DELIM_P (target_path[len-1]))
105 len -= 1;
106 if (len + strlen (last) + 1 > sizeof (concat))
107 {
108 printf ("Path name too long\n");
109 exit (2);
110 }
111 memcpy (concat, target_path, len);
112 concat[len] = '\\';
113 strcpy (concat + len + 1, last);
114 target_path = concat;
115 }
116
117 /* Replace the module. */
118
119 replace_module (target_path, source_path);
120 printf ("\"%s\" replaced with \"%s\".\n", target_path, source_path);
121}
122
123
124static void delete (const char *old_path)
125{
126 replace_module (old_path, NULL);
127 printf ("\"%s\" deleted.\n", old_path);
128}
129
130
131int main (int argc, char *argv[])
132{
133 int c;
134 char delete_flag = FALSE;
135
136 /* This check is not required as we use LINK386 for linking. */
137
138 if (_osmode != OS2_MODE)
139 exit (2);
140
141 /* Parse the command line options. */
142
143 while ((c = getopt (argc, argv, "d")) != -1)
144 switch (c)
145 {
146 case 'd':
147 delete_flag = 1;
148 break;
149 default:
150 usage ();
151 }
152
153 if (delete_flag && argc - optind == 1)
154 delete (argv[optind+0]);
155 else if (!delete_flag && argc - optind == 2)
156 update (argv[optind+0], argv[optind+1]);
157 else
158 usage ();
159 return 0;
160}
Note: See TracBrowser for help on using the repository browser.