source: trunk/dll/pathutil.c@ 1047

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

Minor code cleanup

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