source: trunk/dll/pathutil.c@ 1039

Last change on this file since 1039 was 1039, checked in by Gregg Young, 17 years ago

Removed unnecessary xfrees and included fortify.h where needed; moved several misplaced (x)frees;

File size: 10.1 KB
Line 
1
2/***********************************************************************
3
4 $Id: $
5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2001, 2008 Steven H. Levine
10
11 05 Jan 08 SHL Move from arccnrs.c and comp.c to here
12 06 Jan 08 GKY Add NormalizeCmdLine to check program strings on entry
13 29 Feb 08 GKY Use xfree where appropriate
14 29 Feb 08 GKY Changes to enable user settable command line length
15
16***********************************************************************/
17
18#include <stdlib.h>
19#include <string.h>
20
21#define INCL_WIN
22#define INCL_DOS
23#define INCL_LONGLONG
24
25#include "pathutil.h"
26#include "fm3dll.h" // needs_quoting
27#include "fm3str.h"
28#include "errutil.h" // Dos_Error...
29#include "strutil.h" // GetPString
30#include "fortify.h"
31
32static PSZ pszSrcFile = __FILE__;
33
34// #pragma data_seg(DATA1)
35
36/**
37 * Build full path name in callers buffer given directory
38 * name and filename
39 * @param pszPathName points to drive/directory if not NULL
40 * @returns pointer to full path name in caller's buffer
41 * @note OK for pszFullPathName and pszPathName to point to same buffer
42 *
43 */
44
45PSZ BldFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
46{
47 UINT c = pszPathName ? strlen(pszPathName) : 0;
48 if (c > 0) {
49 memcpy(pszFullPathName, pszPathName, c);
50 if (pszFullPathName[c - 1] != '\\')
51 pszFullPathName[c++] = '\\';
52 }
53 strcpy(pszFullPathName + c, pszFileName);
54 return pszFullPathName;
55}
56
57/**
58 * Build quoted full path name in callers buffer given
59 * directory name and filename
60 * @param pszPathName points to drive/directory if not NULL
61 * @returns pointer to quoted path name in caller's buffer
62 */
63
64PSZ BldQuotedFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
65{
66 UINT c = pszPathName ? strlen(pszPathName) : 0;
67 BOOL q = needs_quoting(pszPathName) ||
68 needs_quoting(pszFileName);
69 PSZ psz = pszFullPathName;
70
71 if (q)
72 *psz++ = '"';
73 if (c > 0) {
74 memcpy(psz, pszPathName, c);
75 psz += c;
76 if (*(psz - 1) != '\\')
77 *psz++ = '\\';
78 }
79 strcpy(psz, pszFileName);
80 if (q) {
81 psz += strlen(psz);
82 *psz++ = '"';
83 *psz = 0;
84 }
85 return pszFullPathName;
86}
87
88/**
89 * Build quoted full path name in callers buffer given a filename
90 * @returns pointer to quoted file name in caller's buffer
91 */
92
93PSZ BldQuotedFileName(PSZ pszQuotedFileName, PSZ pszFileName)
94{
95 BOOL q = needs_quoting(pszFileName);
96 PSZ psz = pszQuotedFileName;
97
98 if (q)
99 *psz++ = '"';
100 strcpy(psz, pszFileName);
101 if (q) {
102 psz += strlen(psz);
103 *psz++ = '"';
104 *psz = 0;
105 }
106 return pszQuotedFileName;
107}
108
109/** NormalizeCmdLine
110 * Checks a command line for common errors (missing quotes, missing extension,
111 * no space between exe and args etc)
112 * Command line passed as pszCmdLine_
113 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
114 * pszWorkBuf. This is where the quoted etc as necessary command
115 * line string will be returned.
116 */
117
118PCSZ NormalizeCmdLine(PSZ pszWorkBuf, PSZ pszCmdLine_)
119{
120 char *szCmdLine, *szArgs;
121 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
122 APIRET ret;
123 ULONG ulAppType;
124 char *pszChar;
125 FILEFINDBUF3 FindBuffer;
126 ULONG ulResultBufLen = sizeof(FILEFINDBUF3);
127 HDIR hdirFindHandle = HDIR_CREATE;
128 ULONG ulFindCount = 1;
129 PSZ pszNewCmdLine = pszWorkBuf;
130
131 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
132 if (!szCmdLine)
133 return pszCmdLine_; //already complained
134 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
135 if (!szArgs) {
136 free(szCmdLine);
137 return pszCmdLine_; //already complained
138 }
139 bstrip(pszCmdLine_);
140 memset(pszWorkBuf, 0, MaxComLineStrg);
141 strcpy(szCmdLine, pszCmdLine_);
142 if (szCmdLine[0] != '\0') {
143 offsetexe = strstr(strlwr(pszCmdLine_), ".exe");
144 offsetcmd = strstr(strlwr(pszCmdLine_), ".cmd");
145 offsetcom = strstr(strlwr(pszCmdLine_), ".com");
146 offsetbtm = strstr(strlwr(pszCmdLine_), ".btm");
147 offsetbat = strstr(strlwr(pszCmdLine_), ".bat");
148 if (offsetexe)
149 offset = offsetexe;
150 else {
151 if (offsetcom)
152 offset = offsetcom;
153 else {
154 if (offsetcmd)
155 offset = offsetcmd;
156 else {
157 if (offsetbtm)
158 offset = offsetbtm;
159 else {
160 if (offsetbat)
161 offset = offsetexe;
162 }
163 }
164 }
165 }
166 if (offset) {
167 szCmdLine[offset + 4 - pszCmdLine_] = '\0';
168 strcpy(szArgs, &pszCmdLine_[offset + 4 - pszCmdLine_]);
169 while (strchr(szCmdLine, '\"'))
170 remove_first_occurence_of_character("\"", szCmdLine);
171 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
172 !strstr(pszCmdLine_, "\\:")||
173 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
174 remove_first_occurence_of_character("\"", szArgs);
175 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
176 saymsg(MB_OK, HWND_DESKTOP,
177 NullStr,
178 GetPString(IDS_QUOTESINARGSTEXT),
179 pszCmdLine_);
180 if (!offsetexe) {
181 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
182 ulResultBufLen, &ulFindCount, FIL_STANDARD);
183 if (ret) {
184 pszChar = szCmdLine;
185 while (pszChar) {
186 if (*pszChar == ' ') {
187 *pszChar = '\0';
188 strcat(szCmdLine, ".exe");
189 ret = DosQueryAppType(szCmdLine, &ulAppType);
190 //printf("%d %s\n", ret, szCmdLine); fflush(stdout);
191 if (!ret) {
192 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
193 break;
194 }
195 }
196 strcpy(szCmdLine, pszCmdLine_);
197 pszChar++;
198 }
199 }
200 }
201 else
202 ret = DosQueryAppType(szCmdLine, &ulAppType);
203 BldQuotedFileName(pszNewCmdLine, szCmdLine);
204 //printf("%d A", ret); fflush(stdout);
205 if (ret) {
206 ret = saymsg(MB_YESNO,
207 HWND_DESKTOP,
208 NullStr,
209 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
210 pszCmdLine_);
211 if (ret == MBID_YES){
212 if (szArgs[0] != ' ')
213 strcat(pszNewCmdLine, " ");
214 strcat(pszNewCmdLine, szArgs);
215 }
216 else{
217 fCancelAction = TRUE;
218 pszNewCmdLine = pszCmdLine_;
219 }
220 }
221 else{
222 if (szArgs[0] != ' ')
223 strcat(pszNewCmdLine, " ");
224 strcat(pszNewCmdLine, szArgs);
225 }
226
227 }
228 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
229 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
230 if (!strchr(szCmdLine, ' ')) {
231 while (strchr(szCmdLine, '\"'))
232 remove_first_occurence_of_character("\"", szCmdLine);
233 strcat(szCmdLine, ".exe");
234 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
235 ulResultBufLen, &ulFindCount, FIL_STANDARD);
236 //printf("%d", ret); fflush(stdout);
237 }
238 else {
239 pszChar = szCmdLine;
240 while (pszChar) {
241 while (strchr(szCmdLine, '\"'))
242 remove_first_occurence_of_character("\"", szCmdLine);
243 if (*pszChar == ' ') {
244 *pszChar = '\0';
245 strcat(szCmdLine, ".exe");
246 ret = DosQueryAppType(szCmdLine, &ulAppType);
247 //printf("%d %s\n", ret, szCmdLine); fflush(stdout);
248 if (!ret) {
249 break;
250 }
251 }
252 strcpy(szCmdLine, pszCmdLine_);
253 pszChar++;
254 }
255 }
256 if (!ret){
257 BldQuotedFileName(pszNewCmdLine, szCmdLine);
258 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
259 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
260 !strstr(pszCmdLine_, "\\:" ) ||
261 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
262 remove_first_occurence_of_character("\"", szArgs);
263 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
264 saymsg(MB_OK, HWND_DESKTOP,
265 NullStr,
266 GetPString(IDS_QUOTESINARGSTEXT),
267 pszCmdLine_);
268 if (szArgs[0] != ' ')
269 strcat(pszNewCmdLine, " ");
270 strcat(pszNewCmdLine, szArgs);
271 }
272 else {
273 ret = saymsg(MB_OK,
274 HWND_DESKTOP,
275 NullStr,
276 GetPString(IDS_PROGRAMNOTEXE2TEXT),
277 pszCmdLine_);
278 fCancelAction = TRUE;
279 pszNewCmdLine = pszCmdLine_;
280 }
281 }
282 else {
283 pszChar = strrchr(szCmdLine, '.');
284 while (pszChar && *pszChar !=' ') {
285 pszChar++;
286 }
287 *pszChar = '\0';
288 strcpy (szArgs, pszCmdLine_ + strlen(szCmdLine));
289 while (strchr(szCmdLine, '\"'))
290 remove_first_occurence_of_character("\"", szCmdLine);
291 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
292 !strstr(pszCmdLine_, "\\:")||
293 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
294 remove_first_occurence_of_character("\"", szArgs);
295 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
296 saymsg(MB_OK, HWND_DESKTOP,
297 NullStr,
298 GetPString(IDS_QUOTESINARGSTEXT),
299 pszCmdLine_);
300 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
301 ulResultBufLen, &ulFindCount, FIL_STANDARD);
302
303 BldQuotedFileName(pszNewCmdLine, szCmdLine);
304 //printf("%d %s ", ret, szCmdLine); fflush(stdout);
305 if (ret) {
306 ret = saymsg(MB_YESNO,
307 HWND_DESKTOP,
308 NullStr,
309 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
310 pszCmdLine_);
311 if (ret == MBID_YES) {
312 if (szArgs[0] != ' ')
313 strcat(pszNewCmdLine, " ");
314 strcat(pszNewCmdLine, szArgs);
315 }
316 else {
317 fCancelAction = TRUE;
318 pszWorkBuf = pszCmdLine_;
319 }
320 }
321 ret = saymsg(MB_YESNOCANCEL,
322 HWND_DESKTOP,
323 NullStr,
324 GetPString(IDS_PROGRAMNOTEXE3TEXT),
325 pszCmdLine_, pszNewCmdLine);
326 if (ret == MBID_YES){
327 if (szArgs[0] != ' ')
328 strcat(pszNewCmdLine, " ");
329 strcat(pszNewCmdLine, szArgs);
330 }
331 if (ret == MBID_CANCEL){
332 fCancelAction = TRUE;
333 pszNewCmdLine = pszCmdLine_;
334 }
335 }
336 }
337 free(szArgs);
338 free(szCmdLine);
339 return pszWorkBuf;
340}
341
342#pragma alloc_text(PATHUTIL,BldFullPathName)
343#pragma alloc_text(PATHUTIL,BldQuotedFileName)
344#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
345#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.