source: trunk/dll/uudecode.c

Last change on this file was 1673, checked in by Gregg Young, 13 years ago

Update to Doxygen comment style Ticket 55. Also some minor code cleanup.

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