source: trunk/dll/uudecode.c@ 1160

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

Ticket 187: Draft 1: Functions only

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