ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Convert-UUlib/UUlib.xs
Revision: 1.20
Committed: Fri Feb 28 17:33:09 2020 UTC (4 years, 2 months ago) by root
Branch: MAIN
CVS Tags: rel-1_7
Changes since 1.19: +83 -111 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include "perlmulticore.h"
6
7 #include "uulib/fptools.h"
8 #include "uulib/uudeview.h"
9 #include "uulib/uuint.h"
10
11 static int perlinterp_released;
12
13 #define RELEASE do { perlinterp_released = 1; perlinterp_release (); } while (0)
14 #define ACQUIRE do { perlinterp_acquire (); perlinterp_released = 0; } while (0)
15
16 #define TEMP_ACQUIRE if (perlinterp_released) perlinterp_acquire ();
17 #define TEMP_RELEASE if (perlinterp_released) perlinterp_release ();
18
19 static void
20 uu_msg_callback (void *cb, char *msg, int level)
21 {
22 TEMP_ACQUIRE {
23
24 dSP;
25
26 ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2);
27
28 PUSHs (sv_2mortal (newSVpv (msg, 0)));
29 PUSHs (sv_2mortal (newSViv (level)));
30
31 PUTBACK; (void) perl_call_sv ((SV *)cb, G_VOID|G_DISCARD); SPAGAIN;
32 PUTBACK; FREETMPS; LEAVE;
33
34 } TEMP_RELEASE;
35 }
36
37 static int
38 uu_busy_callback (void *cb, uuprogress *uup)
39 {
40 int retval;
41
42 TEMP_ACQUIRE {
43
44 dSP;
45 int count;
46
47 ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 6);
48
49 PUSHs (sv_2mortal (newSViv (uup->action)));
50 PUSHs (sv_2mortal (newSVpv (uup->curfile, 0)));
51 PUSHs (sv_2mortal (newSViv (uup->partno)));
52 PUSHs (sv_2mortal (newSViv (uup->numparts)));
53 PUSHs (sv_2mortal (newSViv (uup->fsize)));
54 PUSHs (sv_2mortal (newSViv (uup->percent)));
55
56 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
57
58 if (count != 1)
59 croak ("busycallback perl callback returned more than one argument");
60
61 retval = POPi;
62
63 PUTBACK; FREETMPS; LEAVE;
64
65 } TEMP_RELEASE;
66
67 return retval;
68 }
69
70 static char *
71 uu_fnamefilter_callback (void *cb, char *fname)
72 {
73 static char *str;
74
75 TEMP_ACQUIRE {
76
77 dSP;
78 int count;
79
80 ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 1);
81
82 PUSHs (sv_2mortal (newSVpv (fname, 0)));
83
84 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
85
86 if (count != 1)
87 croak ("fnamefilter perl callback MUST return a single filename exactly");
88
89 _FP_free (str); str = _FP_strdup (SvPV_nolen (TOPs));
90
91 PUTBACK; FREETMPS; LEAVE;
92
93 } TEMP_RELEASE;
94
95 return str;
96 }
97
98 static int
99 uu_file_callback (void *cb, char *id, char *fname, int retrieve)
100 {
101 int retval;
102
103 TEMP_ACQUIRE {
104
105 dSP;
106 int count;
107 SV *xfname = newSVpv ("", 0);
108
109 ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 3);
110
111 PUSHs (sv_2mortal (newSVpv (id, 0)));
112 PUSHs (sv_2mortal (xfname));
113 PUSHs (sv_2mortal (newSViv (retrieve)));
114
115 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
116
117 if (count != 1)
118 croak ("filecallback perl callback must return a single return status");
119
120 strcpy (fname, SvPV_nolen (xfname));
121 retval = POPi;
122
123 PUTBACK; FREETMPS; LEAVE;
124
125 } TEMP_RELEASE;
126
127 return retval;
128 }
129
130 static char *
131 uu_filename_callback (void *cb, char *subject, char *filename)
132 {
133 TEMP_ACQUIRE {
134
135 dSP;
136 int count;
137
138 ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2);
139
140 PUSHs (sv_2mortal(newSVpv(subject, 0)));
141 PUSHs (filename ? sv_2mortal(newSVpv(filename, 0)) : &PL_sv_undef);
142
143 PUTBACK; count = perl_call_sv ((SV *)cb, G_ARRAY); SPAGAIN;
144
145 if (count > 1)
146 croak ("filenamecallback perl callback must return nothing or a single filename");
147
148 if (count)
149 {
150 _FP_free (filename);
151
152 filename = SvOK (TOPs)
153 ? _FP_strdup (SvPV_nolen (TOPs))
154 : 0;
155 }
156
157 PUTBACK; FREETMPS; LEAVE;
158
159 } TEMP_RELEASE;
160
161 return filename;
162 }
163
164 static SV *uu_msg_sv, *uu_busy_sv, *uu_file_sv, *uu_fnamefilter_sv, *uu_filename_sv;
165
166 #define FUNC_CB(cb) (void *)(sv_setsv (cb ## _sv, func), cb ## _sv), func ? cb ## _callback : NULL
167
168 static int
169 uu_info_file (void *cb, char *info)
170 {
171 int retval;
172
173 TEMP_ACQUIRE {
174
175 dSP;
176 int count;
177
178 ENTER; SAVETMPS; PUSHMARK(SP); EXTEND(SP,1);
179
180 PUSHs(sv_2mortal(newSVpv(info,0)));
181
182 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
183
184 if (count != 1)
185 croak ("info_file perl callback returned more than one argument");
186
187 retval = POPi;
188
189 PUTBACK; FREETMPS; LEAVE;
190
191 } TEMP_RELEASE;
192
193 return retval;
194 }
195
196 static int
197 uu_opt_isstring (int opt)
198 {
199 switch (opt)
200 {
201 case UUOPT_VERSION:
202 case UUOPT_SAVEPATH:
203 case UUOPT_ENCEXT:
204 return 1;
205 default:
206 return 0;
207 }
208 }
209
210 static void
211 initialise (void)
212 {
213 int retval = UUInitialize ();
214
215 if (retval != UURET_OK)
216 croak ("unable to initialize uudeview library (%s)", UUstrerror (retval));
217 }
218
219 MODULE = Convert::UUlib PACKAGE = Convert::UUlib PREFIX = UU
220
221 PROTOTYPES: ENABLE
222
223 void
224 UUCleanUp ()
225 CODE:
226 UUCleanUp ();
227 initialise ();
228
229 SV *
230 UUGetOption (opt)
231 int opt
232 CODE:
233 {
234 if (opt == UUOPT_PROGRESS)
235 croak ("GetOption(UUOPT_PROGRESS) is not yet implemented");
236 else if (uu_opt_isstring (opt))
237 {
238 char cval[8192];
239
240 UUGetOption (opt, 0, cval, sizeof cval);
241 RETVAL = newSVpv (cval, 0);
242 }
243 else
244 {
245 RETVAL = newSViv (UUGetOption (opt, 0, 0, 0));
246 }
247 }
248 OUTPUT:
249 RETVAL
250
251 int
252 UUSetOption (opt, val)
253 int opt
254 SV * val
255 CODE:
256 {
257 STRLEN dc;
258
259 if (uu_opt_isstring (opt))
260 RETVAL = UUSetOption (opt, 0, SvPV (val, dc));
261 else
262 RETVAL = UUSetOption (opt, SvIV (val), (void *)0);
263 }
264 OUTPUT:
265 RETVAL
266
267 char *
268 UUstrerror (errcode)
269 int errcode
270
271 void
272 UUSetMsgCallback (func = 0)
273 SV * func
274 CODE:
275 UUSetMsgCallback (FUNC_CB (uu_msg));
276
277 void
278 UUSetBusyCallback (func = 0,msecs = 1000)
279 SV * func
280 long msecs
281 CODE:
282 UUSetBusyCallback (FUNC_CB (uu_busy), msecs);
283
284 void
285 UUSetFileCallback (func = 0)
286 SV * func
287 CODE:
288 UUSetFileCallback (FUNC_CB (uu_file));
289
290 void
291 UUSetFNameFilter (func = 0)
292 SV * func
293 CODE:
294 UUSetFNameFilter (FUNC_CB (uu_fnamefilter));
295
296 void
297 UUSetFileNameCallback (func = 0)
298 SV * func
299 CODE:
300 UUSetFileNameCallback (FUNC_CB (uu_filename));
301
302 char *
303 UUFNameFilter (fname)
304 char * fname
305
306 void
307 UULoadFile (fname, id = 0, delflag = 0, partno = -1)
308 char * fname
309 char * id
310 int delflag
311 int partno
312 PPCODE:
313 {
314 int count;
315 IV ret;
316
317 RELEASE;
318 ret = UULoadFileWithPartNo (fname, id, delflag, partno, &count);
319 ACQUIRE;
320
321 XPUSHs (sv_2mortal (newSViv (ret)));
322 if (GIMME_V == G_ARRAY)
323 XPUSHs (sv_2mortal (newSViv (count)));
324 }
325
326 int
327 UUSmerge (pass)
328 int pass
329
330 int
331 UUQuickDecode(datain,dataout,boundary,maxpos)
332 FILE * datain
333 FILE * dataout
334 char * boundary
335 long maxpos
336
337 int
338 UUEncodeMulti(outfile,infile,infname,encoding,outfname,mimetype,filemode)
339 FILE * outfile
340 FILE * infile
341 char * infname
342 int encoding
343 char * outfname
344 char * mimetype
345 int filemode
346
347 int
348 UUEncodePartial(outfile,infile,infname,encoding,outfname,mimetype,filemode,partno,linperfile)
349 FILE * outfile
350 FILE * infile
351 char * infname
352 int encoding
353 char * outfname
354 char * mimetype
355 int filemode
356 int partno
357 long linperfile
358
359 int
360 UUEncodeToStream(outfile,infile,infname,encoding,outfname,filemode)
361 FILE * outfile
362 FILE * infile
363 char * infname
364 int encoding
365 char * outfname
366 int filemode
367
368 int
369 UUEncodeToFile(infile,infname,encoding,outfname,diskname,linperfile)
370 FILE * infile
371 char * infname
372 int encoding
373 char * outfname
374 char * diskname
375 long linperfile
376
377 int
378 UUE_PrepSingle(outfile,infile,infname,encoding,outfname,filemode,destination,from,subject,isemail)
379 FILE * outfile
380 FILE * infile
381 char * infname
382 int encoding
383 char * outfname
384 int filemode
385 char * destination
386 char * from
387 char * subject
388 int isemail
389
390 int
391 UUE_PrepPartial(outfile,infile,infname,encoding,outfname,filemode,partno,linperfile,filesize,destination,from,subject,isemail)
392 FILE * outfile
393 FILE * infile
394 char * infname
395 int encoding
396 char * outfname
397 int filemode
398 int partno
399 long linperfile
400 long filesize
401 char * destination
402 char * from
403 char * subject
404 int isemail
405
406 uulist *
407 UUGetFileListItem (num)
408 int num
409
410 void
411 GetFileList ()
412 PPCODE:
413 for (uulist *iter = UUGlobalFileList; iter; iter = iter->NEXT)
414 XPUSHs (sv_setref_pv (sv_newmortal (), "Convert::UUlib::Item", iter));
415
416 MODULE = Convert::UUlib PACKAGE = Convert::UUlib::Item
417
418 int
419 rename (item, newname)
420 uulist *item
421 char * newname
422 CODE:
423 RETVAL = UURenameFile (item, newname);
424 OUTPUT:
425 RETVAL
426
427 int
428 decode_temp (item)
429 uulist *item
430 CODE:
431 RELEASE;
432 RETVAL = UUDecodeToTemp (item);
433 ACQUIRE;
434 OUTPUT:
435 RETVAL
436
437 int
438 remove_temp (item)
439 uulist *item
440 CODE:
441 RELEASE;
442 RETVAL = UURemoveTemp (item);
443 ACQUIRE;
444 OUTPUT:
445 RETVAL
446
447 int
448 decode (item, target = 0)
449 uulist *item
450 char * target
451 CODE:
452 RELEASE;
453 RETVAL = UUDecodeFile (item, target);
454 ACQUIRE;
455 OUTPUT:
456 RETVAL
457
458 void
459 info (item, func)
460 uulist *item
461 SV * func
462 CODE:
463 RELEASE;
464 UUInfoFile (item, (void *)func, uu_info_file);
465 ACQUIRE;
466
467 short
468 state(li)
469 uulist *li
470 CODE:
471 RETVAL = li->state;
472 OUTPUT:
473 RETVAL
474
475 short
476 mode(li,newmode=0)
477 uulist *li
478 short newmode
479 CODE:
480 if (newmode)
481 li->mode = newmode;
482 RETVAL = li->mode;
483 OUTPUT:
484 RETVAL
485
486 short
487 uudet(li)
488 uulist *li
489 CODE:
490 RETVAL = li->uudet;
491 OUTPUT:
492 RETVAL
493
494 long
495 size(li)
496 uulist *li
497 CODE:
498 RETVAL = li->size;
499 OUTPUT:
500 RETVAL
501
502 char *
503 filename (li, newfilename = 0)
504 uulist *li
505 char * newfilename
506 CODE:
507 if (newfilename)
508 {
509 _FP_free (li->filename);
510 li->filename = _FP_strdup (newfilename);
511 }
512 RETVAL = li->filename;
513 OUTPUT:
514 RETVAL
515
516 char *
517 subfname (li)
518 uulist *li
519 CODE:
520 RETVAL = li->subfname;
521 OUTPUT:
522 RETVAL
523
524 char *
525 mimeid (li)
526 uulist *li
527 CODE:
528 RETVAL = li->mimeid;
529 OUTPUT:
530 RETVAL
531
532 char *
533 mimetype (li)
534 uulist *li
535 CODE:
536 RETVAL = li->mimetype;
537 OUTPUT:
538 RETVAL
539
540 char *
541 binfile (li)
542 uulist *li
543 CODE:
544 RETVAL = li->binfile;
545 OUTPUT:
546 RETVAL
547
548 # methods accessing internal data(!)
549
550 void
551 parts (li)
552 uulist *li
553 PPCODE:
554 {
555 struct _uufile *p = li->thisfile;
556
557 while (p)
558 {
559 HV *pi = newHV ();
560
561 hv_store (pi, "partno" , 6, newSViv (p->partno) , 0);
562 if (p->filename ) hv_store (pi, "filename", 8, newSVpv (p->filename, 0) , 0);
563 if (p->subfname ) hv_store (pi, "subfname", 8, newSVpv (p->subfname, 0) , 0);
564 if (p->mimeid ) hv_store (pi, "mimeid" , 6, newSVpv (p->mimeid , 0) , 0);
565 if (p->mimetype ) hv_store (pi, "mimetype", 8, newSVpv (p->mimetype, 0) , 0);
566 if (p->data->subject) hv_store (pi, "subject" , 7, newSVpv (p->data->subject,0), 0);
567 if (p->data->origin ) hv_store (pi, "origin" , 6, newSVpv (p->data->origin ,0), 0);
568 if (p->data->sfname ) hv_store (pi, "sfname" , 6, newSVpv (p->data->sfname ,0), 0);
569
570 XPUSHs (sv_2mortal (newRV_noinc ((SV *)pi)));
571
572 p = p->NEXT;
573 }
574 }
575
576 BOOT:
577 {
578 HV *stash = GvSTASH (CvGV (cv));
579
580 static const struct {
581 const char *name;
582 IV iv;
583 } *civ, const_iv[] = {
584 # define const_iv(name, value) { # name, (IV) value },
585 const_iv (ACT_COPYING , UUACT_COPYING)
586 const_iv (ACT_DECODING , UUACT_DECODING)
587 const_iv (ACT_ENCODING , UUACT_ENCODING)
588 const_iv (ACT_IDLE , UUACT_IDLE)
589 const_iv (ACT_SCANNING , UUACT_SCANNING)
590 const_iv (FILE_DECODED , UUFILE_DECODED)
591 const_iv (FILE_ERROR , UUFILE_ERROR)
592 const_iv (FILE_MISPART , UUFILE_MISPART)
593 const_iv (FILE_NOBEGIN , UUFILE_NOBEGIN)
594 const_iv (FILE_NODATA , UUFILE_NODATA)
595 const_iv (FILE_NOEND , UUFILE_NOEND)
596 const_iv (FILE_OK , UUFILE_OK)
597 const_iv (FILE_READ , UUFILE_READ)
598 const_iv (FILE_TMPFILE , UUFILE_TMPFILE)
599 const_iv (MSG_ERROR , UUMSG_ERROR)
600 const_iv (MSG_FATAL , UUMSG_FATAL)
601 const_iv (MSG_MESSAGE , UUMSG_MESSAGE)
602 const_iv (MSG_NOTE , UUMSG_NOTE)
603 const_iv (MSG_PANIC , UUMSG_PANIC)
604 const_iv (MSG_WARNING , UUMSG_WARNING)
605 const_iv (OPT_VERSION , UUOPT_VERSION)
606 const_iv (OPT_FAST , UUOPT_FAST)
607 const_iv (OPT_DUMBNESS , UUOPT_DUMBNESS)
608 const_iv (OPT_BRACKPOL , UUOPT_BRACKPOL)
609 const_iv (OPT_VERBOSE , UUOPT_VERBOSE)
610 const_iv (OPT_DESPERATE, UUOPT_DESPERATE)
611 const_iv (OPT_IGNREPLY , UUOPT_IGNREPLY)
612 const_iv (OPT_OVERWRITE, UUOPT_OVERWRITE)
613 const_iv (OPT_SAVEPATH , UUOPT_SAVEPATH)
614 const_iv (OPT_IGNMODE , UUOPT_IGNMODE)
615 const_iv (OPT_DEBUG , UUOPT_DEBUG)
616 const_iv (OPT_ERRNO , UUOPT_ERRNO)
617 const_iv (OPT_PROGRESS , UUOPT_PROGRESS)
618 const_iv (OPT_USETEXT , UUOPT_USETEXT)
619 const_iv (OPT_PREAMB , UUOPT_PREAMB)
620 const_iv (OPT_TINYB64 , UUOPT_TINYB64)
621 const_iv (OPT_ENCEXT , UUOPT_ENCEXT)
622 const_iv (OPT_REMOVE , UUOPT_REMOVE)
623 const_iv (OPT_MOREMIME , UUOPT_MOREMIME)
624 const_iv (OPT_DOTDOT , UUOPT_DOTDOT)
625 const_iv (OPT_RBUF , UUOPT_RBUF)
626 const_iv (OPT_WBUF , UUOPT_WBUF)
627 const_iv (OPT_AUTOCHECK, UUOPT_AUTOCHECK)
628 const_iv (RET_CANCEL , UURET_CANCEL)
629 const_iv (RET_CONT , UURET_CONT)
630 const_iv (RET_EXISTS , UURET_EXISTS)
631 const_iv (RET_ILLVAL , UURET_ILLVAL)
632 const_iv (RET_IOERR , UURET_IOERR)
633 const_iv (RET_NODATA , UURET_NODATA)
634 const_iv (RET_NOEND , UURET_NOEND)
635 const_iv (RET_NOMEM , UURET_NOMEM)
636 const_iv (RET_OK , UURET_OK)
637 const_iv (RET_UNSUP , UURET_UNSUP)
638 const_iv (B64_ENCODED , B64ENCODED)
639 const_iv (BH_ENCODED , BH_ENCODED)
640 const_iv (PT_ENCODED , PT_ENCODED)
641 const_iv (QP_ENCODED , QP_ENCODED)
642 const_iv (UU_ENCODED , UU_ENCODED)
643 const_iv (XX_ENCODED , XX_ENCODED)
644 const_iv (YENC_ENCODED , YENC_ENCODED)
645 };
646
647 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ > const_iv; civ--)
648 newCONSTSUB (stash, (char *)civ[-1].name, newSViv (civ[-1].iv));
649
650 uu_msg_sv = newSVsv (&PL_sv_undef);
651 uu_busy_sv = newSVsv (&PL_sv_undef);
652 uu_file_sv = newSVsv (&PL_sv_undef);
653 uu_fnamefilter_sv = newSVsv (&PL_sv_undef);
654 uu_filename_sv = newSVsv (&PL_sv_undef);
655
656 initialise ();
657 }
658