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
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){
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 }
[985]331 xfree(szArgs);
332 xfree(szCmdLine);
[920]333 return pszWorkBuf;
334}
335
[907]336#pragma alloc_text(PATHUTIL,BldFullPathName)
337#pragma alloc_text(PATHUTIL,BldQuotedFileName)
338#pragma alloc_text(PATHUTIL,BldQuotedFullPathName)
[920]339#pragma alloc_text(PATHUTIL,NormalizeCmdLine)
Note: See TracBrowser for help on using the repository browser.