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
RevLine 
[907]1
2/***********************************************************************
3
[1323]4 $Id: pathutil.c 1402 2009-03-14 17:17:59Z gyoung $
[907]5
6 Path handling utility functions
7
8 Copyright (c) 1993-98 M. Kimes
[1394]9 Copyright (c) 2001, 2009 Steven H. Levine
[907]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;
[1394]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"
[1398]39#include "stristr.h" //stristr
[907]40
[985]41static PSZ pszSrcFile = __FILE__;
42
[907]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
[1398]54PSZ BldFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
[907]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
[1398]73PSZ BldQuotedFullPathName(PSZ pszFullPathName, PCSZ pszPathName, PCSZ pszFileName)
[907]74{
75 UINT c = pszPathName ? strlen(pszPathName) : 0;
[1161]76 BOOL q = needs_quoting(pszPathName) || needs_quoting(pszFileName);
[907]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
[1394]101PSZ BldQuotedFileName(PSZ pszQuotedFileName, PCSZ pszFileName)
[907]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
[920]117/** NormalizeCmdLine
118 * Checks a command line for common errors (missing quotes, missing extension,
[1248]119 * no space between exe and args etc) Also check for the existance of the file
120 * and checks .com and .exe file headers.
[920]121 * Command line passed as pszCmdLine_
[985]122 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
[920]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{
[985]129 char *szCmdLine, *szArgs;
[920]130 char *offset = '\0', *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
131 APIRET ret;
132 ULONG ulAppType;
133 char *pszChar;
[1247]134 char *FullPath;
[920]135 PSZ pszNewCmdLine = pszWorkBuf;
136
[985]137 szCmdLine = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
138 if (!szCmdLine)
139 return pszCmdLine_; //already complained
140 szArgs = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
141 if (!szArgs) {
[1039]142 free(szCmdLine);
[985]143 return pszCmdLine_; //already complained
144 }
[920]145 bstrip(pszCmdLine_);
[985]146 memset(pszWorkBuf, 0, MaxComLineStrg);
[920]147 strcpy(szCmdLine, pszCmdLine_);
148 if (szCmdLine[0] != '\0') {
[1398]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);
[920]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_);
[1247]186 if (!offsetexe && !offsetcom) {
[1398]187 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]188 if (*FullPath)
189 ret = 0;
[920]190 }
191 else
192 ret = DosQueryAppType(szCmdLine, &ulAppType);
193 BldQuotedFileName(pszNewCmdLine, szCmdLine);
194 if (ret) {
[1394]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);
[920]204 }
[1394]205 else{
206 fCancelAction = TRUE;
207 pszNewCmdLine = pszCmdLine_;
208 }
[920]209 }
210 else{
[1394]211 if (szArgs[0] != ' ')
212 strcat(pszNewCmdLine, " ");
213 strcat(pszNewCmdLine, szArgs);
[920]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, ' ')) {
[1394]221 // strip quotes readded by BuildQuotedFileName
[920]222 while (strchr(szCmdLine, '\"'))
223 remove_first_occurence_of_character("\"", szCmdLine);
[1394]224 ret = DosQueryAppType(szCmdLine, &ulAppType); // exe automatically appended
225 if (!ret)
[1398]226 strcat(szCmdLine, PCSZ_DOTEXE);
[1394]227 else {
[1398]228 strcat(szCmdLine, PCSZ_DOTCOM);
[1394]229 ret = DosQueryAppType(szCmdLine, &ulAppType);
230 if (ret) {
231 offset = strrchr(szCmdLine, '.' );
232 *offset = 0;
[1398]233 strcat(szCmdLine, PCSZ_DOTCMD);
234 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]235 if (*FullPath)
236 ret = 0;
237 else {
238 *offset = 0;
[1398]239 strcat(szCmdLine, PCSZ_DOTBAT);
240 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]241 if (*FullPath)
242 ret = 0;
243 else {
244 *offset = 0;
[1398]245 strcat(szCmdLine, PCSZ_DOTBTM);
246 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]247 if (*FullPath)
248 ret = 0;
249 }
250 }
251 }
252 }
[920]253 }
254 else {
255 pszChar = szCmdLine;
256 while (pszChar) {
257 while (strchr(szCmdLine, '\"'))
258 remove_first_occurence_of_character("\"", szCmdLine);
[1247]259 if (*pszChar == ' ') { //test at every space for the end of the filename
[920]260 *pszChar = '\0';
[1394]261 ret = DosQueryAppType(szCmdLine, &ulAppType);
262 if (!ret) {
[1398]263 strcat(szCmdLine, PCSZ_DOTEXE);
[1394]264 break;
265 }
266 else {
[1398]267 strcat(szCmdLine, PCSZ_DOTCOM);
[1394]268 ret = DosQueryAppType(szCmdLine, &ulAppType);
269 if (ret) {
270 offset = strrchr(szCmdLine, '.' );
271 *offset = 0;
[1398]272 strcat(szCmdLine, PCSZ_DOTCMD);
273 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]274 if (*FullPath) {
275 ret = 0;
276 break;
277 }
278 else {
279 *offset = 0;
[1398]280 strcat(szCmdLine, PCSZ_DOTBAT);
281 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]282 if (*FullPath) {
283 ret = 0;
284 break;
285 }
286 else {
287 *offset = 0;
[1398]288 strcat(szCmdLine, PCSZ_DOTBTM);
289 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[1394]290 if (*FullPath) {
291 ret = 0;
292 break;
293 }
294 }
295 }
296 }
297 else
298 break;
299 }
[920]300 }
301 strcpy(szCmdLine, pszCmdLine_);
302 pszChar++;
303 }
304 }
305 if (!ret){
[1394]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);
[920]320 }
[1248]321 else { // fail if no extension can be found runemf2 requires one
[1394]322 ret = saymsg(MB_OK,
323 HWND_DESKTOP,
324 NullStr,
325 GetPString(IDS_PROGRAMNOTEXE2TEXT),
326 pszCmdLine_);
327 fCancelAction = TRUE;
328 pszNewCmdLine = pszCmdLine_;
[920]329 }
330 }
[1247]331 else { // file has a nonstandard extension for executible
[920]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_);
[1398]349 FullPath = searchapath(PCSZ_PATH, szCmdLine);
[920]350 BldQuotedFileName(pszNewCmdLine, szCmdLine);
[1248]351 if (!*FullPath) {
[920]352 ret = saymsg(MB_YESNO,
353 HWND_DESKTOP,
354 NullStr,
355 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
356 pszCmdLine_);
357 if (ret == MBID_YES) {
[1394]358 if (szArgs[0] != ' ')
359 strcat(pszNewCmdLine, " ");
360 strcat(pszNewCmdLine, szArgs);
[920]361 }
362 else {
363 fCancelAction = TRUE;
364 pszWorkBuf = pszCmdLine_;
365 }
366 }
[1248]367 else {
368 ret = saymsg(MB_YESNOCANCEL,
[1394]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 }
[920]382 }
383 }
384 }
[1039]385 free(szArgs);
386 free(szCmdLine);
[920]387 return pszWorkBuf;
388}
389
[907]390#pragma alloc_text(PATHUTIL,BldFullPathName)
391#pragma alloc_text(PATHUTIL,BldQuotedFileName)
392#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
[920]393#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.