source: trunk/dll/pathutil.c@ 985

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

Update sizes dialog (ticket 44); Make max command line length user settable (ticket 199); use xfree for free in most cases (ticket 212); initial code to check for valid ini file (ticket 102); Some additional refactoring and structure rework; Some documentation updates;

File size: 9.9 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 Use xfree where appropriate
14 29 Feb 08 GKY Changes to enable user settable command line length
15
16***********************************************************************/
17
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
30static PSZ pszSrcFile = __FILE__;
31
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
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_
111 * A pointer to a buffer of the size MaxComLineStrg should be supplied in
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{
118 char *szCmdLine, *szArgs;
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
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 }
137 bstrip(pszCmdLine_);
138 memset(pszWorkBuf, 0, MaxComLineStrg);
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){
210 pszNewCmdLine = pszCmdLine_;
211 }
212 else{
213 fCancelAction = TRUE;
214 pszNewCmdLine = pszCmdLine_;
215 }
216 }
217 else{
218 if (szArgs[0] != ' ')
219 strcat(pszNewCmdLine, " ");
220 strcat(pszNewCmdLine, szArgs);
221 }
222
223 }
224 else if (szCmdLine && (!strchr(szCmdLine, '.') ||
225 strrchr(szCmdLine, '.' ) < strrchr(szCmdLine, '\\'))) {
226 if (!strchr(szCmdLine, ' ')) {
227 while (strchr(szCmdLine, '\"'))
228 remove_first_occurence_of_character("\"", szCmdLine);
229 strcat(szCmdLine, ".exe");
230 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
231 ulResultBufLen, &ulFindCount, FIL_STANDARD);
232 //printf("%d", ret); fflush(stdout);
233 }
234 else {
235 pszChar = szCmdLine;
236 while (pszChar) {
237 while (strchr(szCmdLine, '\"'))
238 remove_first_occurence_of_character("\"", szCmdLine);
239 if (*pszChar == ' ') {
240 *pszChar = '\0';
241 strcat(szCmdLine, ".exe");
242 ret = DosQueryAppType(szCmdLine, &ulAppType);
243 //printf("%d %s\n", ret, szCmdLine); fflush(stdout);
244 if (!ret) {
245 break;
246 }
247 }
248 strcpy(szCmdLine, pszCmdLine_);
249 pszChar++;
250 }
251 }
252 if (!ret){
253 BldQuotedFileName(pszNewCmdLine, szCmdLine);
254 strcpy(szArgs, pszCmdLine_ + strlen(szCmdLine) - 3);
255 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
256 !strstr(pszCmdLine_, "\\:" ) ||
257 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
258 remove_first_occurence_of_character("\"", szArgs);
259 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
260 saymsg(MB_OK, HWND_DESKTOP,
261 NullStr,
262 GetPString(IDS_QUOTESINARGSTEXT),
263 pszCmdLine_);
264 if (szArgs[0] != ' ')
265 strcat(pszNewCmdLine, " ");
266 strcat(pszNewCmdLine, szArgs);
267 }
268 else {
269 ret = saymsg(MB_OK,
270 HWND_DESKTOP,
271 NullStr,
272 GetPString(IDS_PROGRAMNOTEXE2TEXT),
273 pszCmdLine_);
274 fCancelAction = TRUE;
275 pszNewCmdLine = pszCmdLine_;
276 }
277 }
278 else {
279 pszChar = strrchr(szCmdLine, '.');
280 while (pszChar && *pszChar !=' ') {
281 pszChar++;
282 }
283 *pszChar = '\0';
284 strcpy (szArgs, pszCmdLine_ + strlen(szCmdLine));
285 while (strchr(szCmdLine, '\"'))
286 remove_first_occurence_of_character("\"", szCmdLine);
287 if ((szArgs[0] == '\"' && szArgs[1] == ' ') ||
288 !strstr(pszCmdLine_, "\\:")||
289 strchr(szArgs, '\"') == strrchr(szArgs, '\"'))
290 remove_first_occurence_of_character("\"", szArgs);
291 if (strchr(szArgs, '\"') != strrchr(szArgs, '\"'))
292 saymsg(MB_OK, HWND_DESKTOP,
293 NullStr,
294 GetPString(IDS_QUOTESINARGSTEXT),
295 pszCmdLine_);
296 ret = DosFindFirst(szCmdLine, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
297 ulResultBufLen, &ulFindCount, FIL_STANDARD);
298
299 BldQuotedFileName(pszNewCmdLine, szCmdLine);
300 //printf("%d %s ", ret, szCmdLine); fflush(stdout);
301 if (ret) {
302 ret = saymsg(MB_YESNO,
303 HWND_DESKTOP,
304 NullStr,
305 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
306 pszCmdLine_);
307 if (ret == MBID_YES) {
308 pszWorkBuf = pszCmdLine_;
309 }
310 else {
311 fCancelAction = TRUE;
312 pszWorkBuf = pszCmdLine_;
313 }
314 }
315 ret = saymsg(MB_YESNOCANCEL,
316 HWND_DESKTOP,
317 NullStr,
318 GetPString(IDS_PROGRAMNOTEXE3TEXT),
319 pszCmdLine_, pszNewCmdLine);
320 if (ret == MBID_YES){
321 if (szArgs[0] != ' ')
322 strcat(pszNewCmdLine, " ");
323 strcat(pszNewCmdLine, szArgs);
324 }
325 if (ret == MBID_CANCEL){
326 fCancelAction = TRUE;
327 pszNewCmdLine = pszCmdLine_;
328 }
329 }
330 }
331 xfree(szArgs);
332 xfree(szCmdLine);
333 return pszWorkBuf;
334}
335
336#pragma alloc_text(PATHUTIL,BldFullPathName)
337#pragma alloc_text(PATHUTIL,BldQuotedFileName)
338#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
339#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.