source: trunk/dll/pathutil.c@ 1008

Last change on this file since 1008 was 989, checked in by Gregg Young, 18 years ago

Refactor fm3dll.h to create command.h; broken ini is now replaced with backup or new ini as available; more variable command line ledth changes

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