source: trunk/dll/uudecode.c@ 1438

Last change on this file since 1438 was 1438, checked in by Gregg Young, 16 years ago

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 KB
RevLine 
[195]1
2/***********************************************************************
3
4 $Id: uudecode.c 1438 2009-06-28 20:47:00Z gyoung $
5
6 uudecode
7
8 Copyright (c) 1993-98 M. Kimes
[907]9 Copyright (c) 2005, 2008 Steven H. Levine
[195]10
11 06 Jun 05 SHL Indent -i2
[204]12 06 Jun 05 SHL Drop unused code
[328]13 17 Jul 06 SHL Use Runtime_Error
[404]14 29 Jul 06 SHL Use xfgets
[486]15 01 Sep 06 SHL Back to fgets for now - avoid excess error messages
[574]16 22 Mar 07 GKY Use QWL_USER
[793]17 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[1395]18 07 Feb 09 GKY Allow user to turn off alert and/or error beeps in settings notebook.
[195]19
20***********************************************************************/
21
[2]22#include <stdlib.h>
23#include <string.h>
24#include <share.h>
[328]25
[907]26#define INCL_DOS
27#define INCL_WIN
[1160]28#define INCL_LONGLONG // dircnrs.h
[907]29
[1183]30#include "fm3dll.h"
[1228]31#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
32#include "worker.h" // typedef WORKER
[1214]33#include "notebook.h" // Data declaration(s)
[2]34#include "fm3dlg.h"
35#include "fm3str.h"
[1160]36#include "makelist.h" // AddToList
37#include "errutil.h" // Dos_Error...
38#include "strutil.h" // GetPString
39#include "defview.h"
40#include "uudecode.h"
[1183]41#include "getnames.h" // export_filename
42#include "valid.h" // IsFile
43#include "misc.h" // PaintRecessedWindow
44#include "wrappers.h" // xfgets
[1438]45#include "init.h" // Strings
[2]46
[328]47static PSZ pszSrcFile = __FILE__;
48
[2]49/* prototypes */
[195]50static BOOL decode(FILE * in, FILE * out);
51static void outdec(char *p, FILE * f, int n);
[2]52
53/* single character decode */
[1160]54#define DEC(c) (((c) - ' ') & 077)
[2]55
[195]56int UUD(char *filename, CHAR * dest)
57{
58 FILE *in, *out;
59 int mode, ret = 0;
60 char buf[80];
61 char fakedest[CCHMAXPATH];
[2]62
[195]63 if (!dest)
[2]64 dest = fakedest;
[195]65 in = _fsopen(filename, "r", SH_DENYWR);
[486]66 if (!in) {
[2]67 saymsg(MB_CANCEL,
[1160]68 HWND_DESKTOP,
69 GetPString(IDS_ERRORTEXT),
70 GetPString(IDS_COMPCANTOPENTEXT), filename);
[2]71 return ret;
72 }
73
[195]74 /* search for header line */
[486]75 for (;;) {
76 if (!fgets(buf, sizeof(buf), in)) {
[2]77 fclose(in);
78 saymsg(MB_CANCEL,
[1160]79 HWND_DESKTOP,
80 GetPString(IDS_ERRORTEXT),
81 GetPString(IDS_UUDNOBEGINTEXT), filename);
[2]82 return ret;
[195]83 }
84 if (!strncmp(buf, "begin ", 6))
85 break;
[1160]86 } // for
[2]87 *dest = 0;
[195]88 sscanf(buf, "begin %o %259s", &mode, dest);
[2]89 dest[CCHMAXPATH - 1] = 0;
[486]90 {
91 /* place dest in same directory as filename by default... */
[195]92 char build[CCHMAXPATH], *p;
[2]93
[195]94 strcpy(build, filename);
95 p = strrchr(build, '\\');
[486]96 if (p) {
[2]97 p++;
98 *p = 0;
99 }
100 else
[1438]101 strcat(build, PCSZ_BACKSLASH);
[195]102 strncat(build, dest, CCHMAXPATH - strlen(dest));
103 strcpy(dest, build);
[2]104 }
105
[486]106 if (!export_filename(HWND_DESKTOP, dest, FALSE)) {
[2]107 fclose(in);
108 return ret;
109 }
110
[195]111 /* create output file */
112 out = _fsopen(dest, "ab+", SH_DENYWR);
[486]113 if (!out) {
[2]114 fclose(in);
115 saymsg(MB_CANCEL,
[1160]116 HWND_DESKTOP,
117 GetPString(IDS_ERRORTEXT),
118 GetPString(IDS_UUDCANTOPENFORTEXT), dest, filename);
[2]119 return ret;
[195]120 }
[2]121
[204]122 ret = 1;
123 decode(in, out);
[2]124
[551]125 xfgets(buf, sizeof(buf), in, pszSrcFile, __LINE__);
[204]126
[2]127 fclose(in);
128 fclose(out);
129 return ret;
130}
131
132/*
133 * copy from in to out, decoding as you go along.
134 */
[195]135static BOOL decode(FILE * in, FILE * out)
136{
137 char buf[80];
138 char *bp;
139 int n;
[2]140
[486]141 for (;;) {
[195]142 /* for each input line */
[551]143 if (!xfgets(buf, sizeof(buf), in, pszSrcFile, __LINE__))
[2]144 return FALSE;
145 n = DEC(buf[0]);
[195]146 if (n <= 0)
147 break;
148 bp = &buf[1];
[486]149 while (n > 0) {
[195]150 outdec(bp, out, n);
151 bp += 4;
152 n -= 3;
153 }
154 }
[2]155 return TRUE;
156}
157
158/*
159 * output a group of 3 bytes (4 input characters).
160 * the input chars are pointed to by p, they are to
161 * be output to file f. n is used to tell us not to
162 * output all of them at the end of the file.
163 */
[195]164static void outdec(char *p, FILE * f, int n)
165{
[204]166 INT c1, c2, c3;
[2]167
[551]168 c1 = DEC(*p) << 2 | (UINT) DEC(p[1]) >> 4;
169 c2 = DEC(p[1]) << 4 | (UINT) DEC(p[2]) >> 2;
[195]170 c3 = DEC(p[2]) << 6 | DEC(p[3]);
171 if (n >= 1)
172 putc(c1, f);
173 if (n >= 2)
174 putc(c2, f);
175 if (n >= 3)
176 putc(c3, f);
[2]177}
178
[195]179MRESULT EXPENTRY MergeDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
180{
[2]181 WORKER *wk;
182
[551]183 switch (msg) {
[195]184 case WM_INITDLG:
[486]185 if (mp2) {
[574]186 WinSetWindowPtr(hwnd, QWL_USER, mp2);
[195]187 wk = (WORKER *) mp2;
[551]188 if (wk->li && wk->li->list && wk->li->list[0]) {
[1160]189 WinSendDlgItemMsg(hwnd, MRG_TARGETNAME, EM_SETTEXTLIMIT,
190 MPFROM2SHORT(CCHMAXPATH, 0), MPVOID);
191 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
[2]192 }
193 else
[1160]194 WinDismissDlg(hwnd, 0);
[195]195 }
196 else
197 WinDismissDlg(hwnd, 0);
198 break;
[2]199
[195]200 case UM_UNDO:
201 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
[574]202 wk = WinQueryWindowPtr(hwnd, QWL_USER);
[486]203 if (wk) {
[195]204 INT x, numfiles = 0;
205 SHORT start;
206 CHAR *p;
[2]207
[551]208 WinSetDlgItemText(hwnd, MRG_TARGETNAME, wk->li->targetpath);
[195]209 start = 0;
[551]210 p = strrchr(wk->li->targetpath, '\\');
[195]211 if (p)
[1160]212 start = (p + 1) - wk->li->targetpath;
[195]213 WinSendDlgItemMsg(hwnd, MRG_TARGETNAME, EM_SETSEL,
[1160]214 MPFROM2SHORT(start, CCHMAXPATH), MPVOID);
[551]215 for (x = 0; wk->li->list[x]; x++) {
[1160]216 if (IsFile(wk->li->list[x]) == 1) {
217 numfiles++;
218 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_INSERTITEM,
219 MPFROM2SHORT(LIT_END, 0),
220 MPFROMP(wk->li->list[x]));
221 }
[2]222 }
[551]223 WinCheckButton(hwnd, MRG_BINARY, (wk->li->type == IDM_MERGEBINARY));
[486]224 if (!numfiles) {
[1160]225 saymsg(MB_CANCEL | MB_ICONEXCLAMATION,
226 hwnd,
227 GetPString(IDS_SILLYERRORTEXT),
228 GetPString(IDS_MERGEWASTETEXT));
229 WinDismissDlg(hwnd, 0);
[195]230 }
231 }
232 return 0;
[2]233
[195]234 case WM_CONTROL:
[551]235 switch (SHORT1FROMMP(mp1)) {
[195]236 case MRG_LISTBOX:
[551]237 switch (SHORT2FROMMP(mp1)) {
[195]238 case LN_ENTER:
[1160]239 {
240 SHORT x;
241 CHAR szBuffer[CCHMAXPATH];
[2]242
[1160]243 x = (SHORT) WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYSELECTION,
244 MPFROMSHORT(LIT_FIRST), MPVOID);
245 if (x >= 0) {
246 *szBuffer = 0;
247 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYITEMTEXT,
248 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
249 if (*szBuffer)
250 QuickEdit(hwnd, szBuffer);
251 }
252 }
253 break;
[2]254 }
255 break;
[195]256 }
257 break;
[2]258
[195]259 case WM_ADJUSTWINDOWPOS:
260 PostMsg(hwnd, UM_SETDIR, MPVOID, MPVOID);
261 break;
[2]262
[195]263 case UM_SETDIR:
[551]264 PaintRecessedWindow(WinWindowFromID(hwnd, MRG_HELP), (HPS) 0, FALSE,
[1160]265 TRUE);
[195]266 return 0;
[2]267
[195]268 case WM_COMMAND:
[551]269 switch (SHORT1FROMMP(mp1)) {
[195]270 case IDM_UNDO:
271 PostMsg(hwnd, UM_UNDO, MPVOID, MPVOID);
272 break;
[2]273
[195]274 case MRG_CHANGETARGET:
[574]275 wk = WinQueryWindowPtr(hwnd, QWL_USER);
[486]276 if (wk) {
[1160]277 CHAR filename[CCHMAXPATH];
[2]278
[1160]279 strcpy(filename, wk->li->targetpath);
280 if (export_filename(HWND_DESKTOP, filename, FALSE) && *filename) {
281 strcpy(wk->li->targetpath, filename);
282 WinSetDlgItemText(hwnd, MRG_TARGETNAME, wk->li->targetpath);
283 }
[195]284 }
285 break;
[2]286
[195]287 case MRG_REMOVE:
288 {
[1160]289 SHORT x;
[2]290
[1160]291 x = (SHORT) WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYSELECTION,
292 MPFROMSHORT(LIT_FIRST), MPVOID);
293 if (x >= 0)
294 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_DELETEITEM,
295 MPFROMSHORT(x), MPVOID);
[195]296 }
297 break;
[2]298
[195]299 case MRG_BOTTOM:
300 case MRG_TOP:
301 {
[1160]302 SHORT x;
303 CHAR szBuffer[CCHMAXPATH];
[2]304
[1160]305 x = (SHORT) WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYSELECTION,
306 MPFROMSHORT(LIT_FIRST), MPVOID);
307 if (x >= 0) {
308 *szBuffer = 0;
309 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_QUERYITEMTEXT,
310 MPFROM2SHORT(x, CCHMAXPATH), MPFROMP(szBuffer));
311 if (*szBuffer) {
312 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_DELETEITEM,
313 MPFROMSHORT(x), MPVOID);
314 if (SHORT1FROMMP(mp1) == MRG_TOP)
315 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_INSERTITEM,
316 MPFROM2SHORT(0, 0), MPFROMP(szBuffer));
317 else
318 WinSendDlgItemMsg(hwnd, MRG_LISTBOX, LM_INSERTITEM,
319 MPFROM2SHORT(LIT_END, 0), MPFROMP(szBuffer));
320 }
321 }
[195]322 }
323 break;
[2]324
[195]325 case DID_CANCEL:
326 WinDismissDlg(hwnd, 0);
327 break;
[2]328
[195]329 case IDM_HELP:
330 if (hwndHelp)
[1160]331 WinSendMsg(hwndHelp, HM_DISPLAY_HELP,
332 MPFROM2SHORT(HELP_MERGE, 0), MPFROMSHORT(HM_RESOURCEID));
[195]333 break;
[2]334
[195]335 case DID_OK:
[574]336 wk = WinQueryWindowPtr(hwnd, QWL_USER);
[486]337 if (wk) {
[1160]338 BOOL append, binary;
339 CHAR **list = NULL, **test, szBuffer[CCHMAXPATH];
340 UINT numfiles = 0, numalloc = 0;
341 INT error;
342 SHORT x, y;
[2]343
[1160]344 *szBuffer = 0;
345 WinQueryDlgItemText(hwnd, MRG_TARGETNAME, CCHMAXPATH, szBuffer);
346 if (!*szBuffer) {
[1395]347 if (!fAlertBeepOff)
348 DosBeep(50, 100);
[1160]349 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, MRG_TARGETNAME));
350 break;
351 }
352 if (DosQueryPathInfo(szBuffer,
353 FIL_QUERYFULLNAME,
354 wk->li->targetpath, CCHMAXPATH)) {
[1395]355 if (!fAlertBeepOff)
356 DosBeep(50, 100);
[1160]357 WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwnd, MRG_TARGETNAME));
358 break;
359 }
360 WinSetDlgItemText(hwnd, MRG_TARGETNAME, szBuffer);
361 append = WinQueryButtonCheckstate(hwnd, MRG_APPEND);
362 binary = WinQueryButtonCheckstate(hwnd, MRG_BINARY);
363 wk->li->type = (append && binary) ? IDM_MERGEBINARYAPPEND :
364 (append) ? IDM_MERGETEXTAPPEND :
365 (binary) ? IDM_MERGEBINARY : IDM_MERGETEXT;
366 x = (SHORT) WinSendDlgItemMsg(hwnd,
367 MRG_LISTBOX,
368 LM_QUERYITEMCOUNT, MPVOID, MPVOID);
369 for (y = 0; y < x; y++) {
370 *szBuffer = 0;
371 WinSendDlgItemMsg(hwnd,
372 MRG_LISTBOX,
373 LM_QUERYITEMTEXT,
374 MPFROM2SHORT(y, CCHMAXPATH), MPFROMP(szBuffer));
375 if (*szBuffer) {
376 error = AddToList(szBuffer, &list, &numfiles, &numalloc);
377 if (error) {
378 Runtime_Error(pszSrcFile, __LINE__, "AddToList");
379 break;
380 }
381 }
382 }
383 if (numfiles && list && numfiles + 1 < numalloc) {
384 test =
385 xrealloc(list, sizeof(CHAR *) * (numfiles + 1), pszSrcFile,
386 __LINE__);
387 if (test)
388 list = test;
389 }
390 if (!list || !list[0]) {
[1398]391 Runtime_Error(pszSrcFile, __LINE__, NULL);
[1160]392 break;
393 }
394 else {
395 FreeList(wk->li->list);
396 wk->li->list = list;
397 }
[2]398 }
[195]399 WinDismissDlg(hwnd, 1);
400 break;
[1160]401 } // switch WM_COMMAND mp1
[195]402 return 0;
[1160]403 } // switch msg
[195]404 return WinDefDlgProc(hwnd, msg, mp1, mp2);
[2]405}
[793]406
407#pragma alloc_text(UUD,UUD,decode,outdec)
408#pragma alloc_text(MERGE,MergeDlgProc)
Note: See TracBrowser for help on using the repository browser.