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