source: trunk/dll/pathutil.c@ 1185

Last change on this file since 1185 was 1185, checked in by John Small, 17 years ago

Ticket 187: Draft 2: Move remaining function declarations

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