source: trunk/dll/pathutil.c@ 1248

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

Cleanup of NormalizeCmdLine changes

File size: 12.3 KB
RevLine 
[907]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
[920]12 06 Jan 08 GKY Add NormalizeCmdLine to check program strings on entry
[985]13 29 Feb 08 GKY Changes to enable user settable command line length
[1247]14 15 Oct 08 GKY Fix NormalizeCmdLine to check all 5 executible extensions when no extension provided;
15 use searchapath to check for existance of file types not checked by DosQAppType;
16 close DosFind.
[907]17
18***********************************************************************/
19
[1039]20#include <stdlib.h>
[907]21#include <string.h>
22
23#define INCL_WIN
[920]24#define INCL_DOS
[907]25#define INCL_LONGLONG
26
[1185]27#include "fm3dll.h" // needs_quoting
[1211]28#include "notebook.h" // Data declaration(s)
29#include "init.h" // Data declaration(s)
[1185]30#include "fm3str.h"
[1247]31#include "srchpath.h" // searchapath
[907]32#include "pathutil.h"
[1161]33#include "strips.h" // remove_first_occurence_of_character
[1185]34#include "valid.h" // needs_quoting
[920]35#include "errutil.h" // Dos_Error...
36#include "strutil.h" // GetPString
[1185]37#include "wrappers.h" // xmalloc
[1039]38#include "fortify.h"
[907]39
[985]40static PSZ pszSrcFile = __FILE__;
41
[907]42// #pragma data_seg(DATA1)
43
44/**
45 * Build full path name in callers buffer given directory
46 * name and filename
47 * @param pszPathName points to drive/directory if not NULL
48 * @returns pointer to full path name in caller's buffer
49 * @note OK for pszFullPathName and pszPathName to point to same buffer
50 *
51 */
52
53PSZ BldFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
54{
55 UINT c = pszPathName ? strlen(pszPathName) : 0;
56 if (c > 0) {
57 memcpy(pszFullPathName, pszPathName, c);
58 if (pszFullPathName[c - 1] != '\\')
59 pszFullPathName[c++] = '\\';
60 }
61 strcpy(pszFullPathName + c, pszFileName);
62 return pszFullPathName;
63}
64
65/**
66 * Build quoted full path name in callers buffer given
67 * directory name and filename
68 * @param pszPathName points to drive/directory if not NULL
69 * @returns pointer to quoted path name in caller's buffer
70 */
71
72PSZ BldQuotedFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)
73{
74 UINT c = pszPathName ? strlen(pszPathName) : 0;
[1161]75 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
[907]76 PSZ psz = pszFullPathName;
77
78 if (q)
79 *psz++ = '"';
80 if (c > 0) {
81 memcpy(psz, pszPathName, c);
82 psz += c;
83 if (*(psz - 1) != '\\')
84 *psz++ = '\\';
85 }
86 strcpy(psz, pszFileName);
87 if (q) {
88 psz += strlen(psz);
89 *psz++ = '"';
90 *psz = 0;
91 }
92 return pszFullPathName;
93}
94
95/**
96 * Build quoted full path name in callers buffer given a filename
97 * @returns pointer to quoted file name in caller's buffer
98 */
99
100PSZ BldQuotedFileName(PSZ pszQuotedFileName, PSZ pszFileName)
101{
102 BOOL q = needs_quoting(pszFileName);
103 PSZ psz = pszQuotedFileName;
104
105 if (q)
106 *psz++ = '"';
107 strcpy(psz, pszFileName);
108 if (q) {
109 psz += strlen(psz);
110 *psz++ = '"';
111 *psz = 0;
112 }
113 return pszQuotedFileName;
114}
115
[920]116/** NormalizeCmdLine
117 * Checks a command line for common errors (missing quotes, missing extension,
[1248]118 * no space between exe and args etc) Also check for the existance of the file
119 * and checks .com and .exe file headers.
[920]120 * Command line passed as pszCmdLine_
[985]121 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
[920]122 * pszWorkBuf. This is where the quoted etc as necessary command
123 * line string will be returned.
124 */
125
126PCSZ NormalizeCmdLine(PSZ pszWorkBuf, PSZ pszCmdLine_)
127{
[985]128 char *szCmdLine, *szArgs;
[920]129 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
130 APIRET ret;
131 ULONG ulAppType;
132 char *pszChar;
[1247]133 char *FullPath;
[920]134 PSZ pszNewCmdLine = pszWorkBuf;
135
[985]136 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
137 if (!szCmdLine)
138 return pszCmdLine_; //already complained
139 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
140 if (!szArgs) {
[1039]141 free(szCmdLine);
[985]142 return pszCmdLine_; //already complained
143 }
[920]144 bstrip(pszCmdLine_);
[985]145 memset(pszWorkBuf, 0, MaxComLineStrg);
[920]146 strcpy(szCmdLine, pszCmdLine_);
147 if (szCmdLine[0] != '\0') {
148 offsetexe = strstr(strlwr(pszCmdLine_), ".exe");
149 offsetcmd = strstr(strlwr(pszCmdLine_), ".cmd");
150 offsetcom = strstr(strlwr(pszCmdLine_), ".com");
151 offsetbtm = strstr(strlwr(pszCmdLine_), ".btm");
152 offsetbat = strstr(strlwr(pszCmdLine_), ".bat");
153 if (offsetexe)
154 offset = offsetexe;
155 else {
156 if (offsetcom)
157 offset = offsetcom;
158 else {
159 if (offsetcmd)
160 offset = offsetcmd;
161 else {
162 if (offsetbtm)
163 offset = offsetbtm;
164 else {
165 if (offsetbat)
166 offset = offsetexe;
167 }
168 }
169 }
170 }
171 if (offset) {
172 szCmdLine[offset + 4 - pszCmdLine_] = '\0';
173 strcpy(szArgs, &pszCmdLine_[offset + 4 - pszCmdLine_]);
174 while (strchr(szCmdLine, '\"'))
175 remove_first_occurence_of_character("\"", szCmdLine);
176 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
177 !strstr(pszCmdLine_, "\\:")||
178 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
179 remove_first_occurence_of_character("\"", szArgs);
180 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
181 saymsg(MB_OK, HWND_DESKTOP,
182 NullStr,
183 GetPString(IDS_QUOTESINARGSTEXT),
184 pszCmdLine_);
[1247]185 if (!offsetexe && !offsetcom) {
[1248]186 FullPath = searchapath("PATH", szCmdLine);
187 if (*FullPath)
188 ret = 0;
[920]189 }
190 else
191 ret = DosQueryAppType(szCmdLine, &ulAppType);
192 BldQuotedFileName(pszNewCmdLine, szCmdLine);
193 //printf("%d A", ret); fflush(stdout);
194 if (ret) {
195 ret = saymsg(MB_YESNO,
196 HWND_DESKTOP,
197 NullStr,
198 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
199 pszCmdLine_);
200 if (ret == MBID_YES){
[989]201 if (szArgs[0] != ' ')
202 strcat(pszNewCmdLine, " ");
203 strcat(pszNewCmdLine, szArgs);
[920]204 }
205 else{
206 fCancelAction = TRUE;
207 pszNewCmdLine = pszCmdLine_;
208 }
209 }
210 else{
211 if (szArgs[0] != ' ')
212 strcat(pszNewCmdLine, " ");
213 strcat(pszNewCmdLine, szArgs);
214 }
215
216 }
[1247]217 // if it doesn't have an extension try it with all the standard ones and add if found
[920]218 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
[1247]219 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
[920]220 if (!strchr(szCmdLine, ' ')) {
[1247]221 // strip quotes readded by BuildQuotedFileName
[920]222 while (strchr(szCmdLine, '\"'))
223 remove_first_occurence_of_character("\"", szCmdLine);
[1248]224 ret = DosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
[1247]225 if (!ret)
226 strcat(szCmdLine, ".exe");
227 else {
228 strcat(szCmdLine, ".com");
229 ret = DosQueryAppType(szCmdLine, &ulAppType);
230 if (ret) {
231 offset = strrchr(szCmdLine, '.' );
232 *offset = 0;
233 strcat(szCmdLine, ".cmd");
234 FullPath = searchapath("PATH", szCmdLine);
[1248]235 if (*FullPath)
[1247]236 ret = 0;
237 else {
238 *offset = 0;
239 strcat(szCmdLine, ".bat");
240 FullPath = searchapath("PATH", szCmdLine);
[1248]241 if (*FullPath)
[1247]242 ret = 0;
243 else {
244 *offset = 0;
245 strcat(szCmdLine, ".bmt");
246 FullPath = searchapath("PATH", szCmdLine);
[1248]247 if (*FullPath)
[1247]248 ret = 0;
249 }
250 }
251 }
252 }
[920]253 //printf("%d", ret); fflush(stdout);
254 }
255 else {
256 pszChar = szCmdLine;
257 while (pszChar) {
258 while (strchr(szCmdLine, '\"'))
259 remove_first_occurence_of_character("\"", szCmdLine);
[1247]260 if (*pszChar == ' ') { //test at every space for the end of the filename
[920]261 *pszChar = '\0';
[1247]262 ret = DosQueryAppType(szCmdLine, &ulAppType);
263 if (!ret) {
264 strcat(szCmdLine, ".exe");
265 break;
266 }
267 else {
268 strcat(szCmdLine, ".com");
269 ret = DosQueryAppType(szCmdLine, &ulAppType);
270 if (ret) {
271 offset = strrchr(szCmdLine, '.' );
272 *offset = 0;
273 strcat(szCmdLine, ".cmd");
274 FullPath = searchapath("PATH", szCmdLine);
[1248]275 if (*FullPath) {
[1247]276 ret = 0;
277 break;
278 }
279 else {
280 *offset = 0;
281 strcat(szCmdLine, ".bat");
282 FullPath = searchapath("PATH", szCmdLine);
[1248]283 if (*FullPath) {
[1247]284 ret = 0;
285 break;
286 }
287 else {
288 *offset = 0;
289 strcat(szCmdLine, ".bmt");
290 FullPath = searchapath("PATH", szCmdLine);
[1248]291 if (*FullPath) {
[1247]292 ret = 0;
293 break;
294 }
295 }
296 }
297 }
298 else
299 break;
300 }
[920]301 //printf("%d %s\n", ret, szCmdLine); fflush(stdout);
302 }
303 strcpy(szCmdLine, pszCmdLine_);
304 pszChar++;
305 }
306 }
307 if (!ret){
308 BldQuotedFileName(pszNewCmdLine, szCmdLine);
309 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
310 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
311 !strstr(pszCmdLine_, "\\:" ) ||
312 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
313 remove_first_occurence_of_character("\"", szArgs);
314 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
315 saymsg(MB_OK, HWND_DESKTOP,
316 NullStr,
317 GetPString(IDS_QUOTESINARGSTEXT),
318 pszCmdLine_);
319 if (szArgs[0] != ' ')
320 strcat(pszNewCmdLine, " ");
321 strcat(pszNewCmdLine, szArgs);
322 }
[1248]323 else { // fail if no extension can be found runemf2 requires one
[920]324 ret = saymsg(MB_OK,
325 HWND_DESKTOP,
326 NullStr,
327 GetPString(IDS_PROGRAMNOTEXE2TEXT),
328 pszCmdLine_);
329 fCancelAction = TRUE;
330 pszNewCmdLine = pszCmdLine_;
331 }
332 }
[1247]333 else { // file has a nonstandard extension for executible
[920]334 pszChar = strrchr(szCmdLine, '.');
335 while (pszChar && *pszChar !=' ') {
336 pszChar++;
337 }
338 *pszChar = '\0';
339 strcpy (szArgs, pszCmdLine_ + strlen(szCmdLine));
340 while (strchr(szCmdLine, '\"'))
341 remove_first_occurence_of_character("\"", szCmdLine);
342 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
343 !strstr(pszCmdLine_, "\\:")||
344 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
345 remove_first_occurence_of_character("\"", szArgs);
346 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
347 saymsg(MB_OK, HWND_DESKTOP,
348 NullStr,
349 GetPString(IDS_QUOTESINARGSTEXT),
350 pszCmdLine_);
[1248]351 FullPath = searchapath("PATH", szCmdLine);
[920]352 BldQuotedFileName(pszNewCmdLine, szCmdLine);
353 //printf("%d %s ", ret, szCmdLine); fflush(stdout);
[1248]354 if (!*FullPath) {
[920]355 ret = saymsg(MB_YESNO,
356 HWND_DESKTOP,
357 NullStr,
358 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
359 pszCmdLine_);
360 if (ret == MBID_YES) {
[989]361 if (szArgs[0] != ' ')
362 strcat(pszNewCmdLine, " ");
363 strcat(pszNewCmdLine, szArgs);
[920]364 }
365 else {
366 fCancelAction = TRUE;
367 pszWorkBuf = pszCmdLine_;
368 }
369 }
[1248]370 else {
371 ret = saymsg(MB_YESNOCANCEL,
[920]372 HWND_DESKTOP,
373 NullStr,
374 GetPString(IDS_PROGRAMNOTEXE3TEXT),
375 pszCmdLine_, pszNewCmdLine);
[1248]376 if (ret == MBID_YES){
377 if (szArgs[0] != ' ')
378 strcat(pszNewCmdLine, " ");
379 strcat(pszNewCmdLine, szArgs);
380 }
381 if (ret == MBID_CANCEL){
382 fCancelAction = TRUE;
383 pszNewCmdLine = pszCmdLine_;
384 }
[920]385 }
386 }
387 }
[1039]388 free(szArgs);
389 free(szCmdLine);
[920]390 return pszWorkBuf;
391}
392
[907]393#pragma alloc_text(PATHUTIL,BldFullPathName)
394#pragma alloc_text(PATHUTIL,BldQuotedFileName)
395#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
[920]396#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.