source: trunk/dll/pathutil.c@ 1545

Last change on this file since 1545 was 1545, checked in by Gregg Young, 15 years ago

Added ForwardslashToBackslash function to streamline code.

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