source: trunk/dll/pathutil.c@ 1402

Last change on this file since 1402 was 1402, checked in by Gregg Young, 16 years ago

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

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