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

# User Rev Content
1 root 1.1 #include "EXTERN.h"
2     #include "perl.h"
3     #include "XSUB.h"
4    
5 root 1.17 #include "perlmulticore.h"
6    
7 root 1.1 #include "uulib/fptools.h"
8 root 1.2 #include "uulib/uudeview.h"
9 root 1.1 #include "uulib/uuint.h"
10    
11 root 1.19 static int perlinterp_released;
12 root 1.17
13 root 1.19 #define RELEASE do { perlinterp_released = 1; perlinterp_release (); } while (0)
14     #define ACQUIRE do { perlinterp_acquire (); perlinterp_released = 0; } while (0)
15 root 1.17
16 root 1.19 #define TEMP_ACQUIRE if (perlinterp_released) perlinterp_acquire ();
17     #define TEMP_RELEASE if (perlinterp_released) perlinterp_release ();
18 root 1.17
19 root 1.8 static void
20     uu_msg_callback (void *cb, char *msg, int level)
21 root 1.1 {
22 root 1.17 TEMP_ACQUIRE {
23    
24 root 1.19 dSP;
25    
26     ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2);
27 root 1.1
28 root 1.19 PUSHs (sv_2mortal (newSVpv (msg, 0)));
29     PUSHs (sv_2mortal (newSViv (level)));
30 root 1.1
31 root 1.19 PUTBACK; (void) perl_call_sv ((SV *)cb, G_VOID|G_DISCARD); SPAGAIN;
32     PUTBACK; FREETMPS; LEAVE;
33 root 1.17
34     } TEMP_RELEASE;
35 root 1.1 }
36    
37 root 1.8 static int
38     uu_busy_callback (void *cb, uuprogress *uup)
39 root 1.1 {
40 root 1.17 int retval;
41    
42     TEMP_ACQUIRE {
43    
44 root 1.19 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 root 1.1
56 root 1.19 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
57 root 1.1
58 root 1.19 if (count != 1)
59     croak ("busycallback perl callback returned more than one argument");
60 root 1.1
61 root 1.19 retval = POPi;
62 root 1.1
63 root 1.19 PUTBACK; FREETMPS; LEAVE;
64 root 1.1
65 root 1.17 } TEMP_RELEASE;
66    
67 root 1.1 return retval;
68     }
69    
70 root 1.8 static char *
71     uu_fnamefilter_callback (void *cb, char *fname)
72 root 1.1 {
73 root 1.17 static char *str;
74    
75     TEMP_ACQUIRE {
76    
77 root 1.19 dSP;
78     int count;
79    
80     ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 1);
81 root 1.1
82 root 1.19 PUSHs (sv_2mortal (newSVpv (fname, 0)));
83 root 1.1
84 root 1.19 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
85 root 1.1
86 root 1.19 if (count != 1)
87     croak ("fnamefilter perl callback MUST return a single filename exactly");
88 root 1.1
89 root 1.19 _FP_free (str); str = _FP_strdup (SvPV_nolen (TOPs));
90 root 1.1
91 root 1.19 PUTBACK; FREETMPS; LEAVE;
92 root 1.1
93 root 1.17 } TEMP_RELEASE;
94    
95 root 1.1 return str;
96     }
97    
98 root 1.8 static int
99     uu_file_callback (void *cb, char *id, char *fname, int retrieve)
100 root 1.1 {
101 root 1.17 int retval;
102    
103     TEMP_ACQUIRE {
104    
105 root 1.19 dSP;
106     int count;
107     SV *xfname = newSVpv ("", 0);
108    
109     ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 3);
110 root 1.1
111 root 1.19 PUSHs (sv_2mortal (newSVpv (id, 0)));
112     PUSHs (sv_2mortal (xfname));
113     PUSHs (sv_2mortal (newSViv (retrieve)));
114 root 1.1
115 root 1.19 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
116 root 1.1
117 root 1.19 if (count != 1)
118     croak ("filecallback perl callback must return a single return status");
119 root 1.1
120 root 1.19 strcpy (fname, SvPV_nolen (xfname));
121     retval = POPi;
122 root 1.1
123 root 1.19 PUTBACK; FREETMPS; LEAVE;
124 root 1.1
125 root 1.17 } TEMP_RELEASE;
126    
127 root 1.1 return retval;
128     }
129    
130 root 1.8 static char *
131     uu_filename_callback (void *cb, char *subject, char *filename)
132 root 1.5 {
133 root 1.17 TEMP_ACQUIRE {
134    
135 root 1.19 dSP;
136     int count;
137    
138     ENTER; SAVETMPS; PUSHMARK (SP); EXTEND (SP, 2);
139 root 1.5
140 root 1.19 PUSHs (sv_2mortal(newSVpv(subject, 0)));
141     PUSHs (filename ? sv_2mortal(newSVpv(filename, 0)) : &PL_sv_undef);
142 root 1.5
143 root 1.19 PUTBACK; count = perl_call_sv ((SV *)cb, G_ARRAY); SPAGAIN;
144 root 1.5
145 root 1.19 if (count > 1)
146     croak ("filenamecallback perl callback must return nothing or a single filename");
147 root 1.5
148 root 1.19 if (count)
149     {
150     _FP_free (filename);
151 root 1.5
152 root 1.19 filename = SvOK (TOPs)
153     ? _FP_strdup (SvPV_nolen (TOPs))
154     : 0;
155     }
156 root 1.5
157 root 1.19 PUTBACK; FREETMPS; LEAVE;
158 root 1.5
159 root 1.17 } TEMP_RELEASE;
160    
161 root 1.5 return filename;
162     }
163    
164     static SV *uu_msg_sv, *uu_busy_sv, *uu_file_sv, *uu_fnamefilter_sv, *uu_filename_sv;
165 root 1.1
166     #define FUNC_CB(cb) (void *)(sv_setsv (cb ## _sv, func), cb ## _sv), func ? cb ## _callback : NULL
167    
168 root 1.8 static int
169     uu_info_file (void *cb, char *info)
170 root 1.1 {
171 root 1.17 int retval;
172    
173     TEMP_ACQUIRE {
174    
175 root 1.19 dSP;
176     int count;
177    
178     ENTER; SAVETMPS; PUSHMARK(SP); EXTEND(SP,1);
179 root 1.1
180 root 1.19 PUSHs(sv_2mortal(newSVpv(info,0)));
181 root 1.1
182 root 1.19 PUTBACK; count = perl_call_sv ((SV *)cb, G_SCALAR); SPAGAIN;
183 root 1.1
184 root 1.19 if (count != 1)
185     croak ("info_file perl callback returned more than one argument");
186 root 1.1
187 root 1.19 retval = POPi;
188 root 1.1
189 root 1.19 PUTBACK; FREETMPS; LEAVE;
190 root 1.1
191 root 1.17 } TEMP_RELEASE;
192    
193 root 1.1 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 root 1.19 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 root 1.1
219     MODULE = Convert::UUlib PACKAGE = Convert::UUlib PREFIX = UU
220    
221     PROTOTYPES: ENABLE
222    
223     void
224 root 1.8 UUCleanUp ()
225 root 1.1 CODE:
226 root 1.19 UUCleanUp ();
227     initialise ();
228 root 1.1
229     SV *
230 root 1.8 UUGetOption (opt)
231 root 1.1 int opt
232     CODE:
233 root 1.16 {
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 root 1.1 OUTPUT:
249     RETVAL
250    
251     int
252 root 1.8 UUSetOption (opt, val)
253 root 1.1 int opt
254     SV * val
255     CODE:
256 root 1.16 {
257     STRLEN dc;
258 root 1.1
259 root 1.16 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 root 1.1 OUTPUT:
265     RETVAL
266    
267     char *
268 root 1.8 UUstrerror (errcode)
269 root 1.1 int errcode
270    
271     void
272 root 1.8 UUSetMsgCallback (func = 0)
273 root 1.1 SV * func
274     CODE:
275 root 1.13 UUSetMsgCallback (FUNC_CB (uu_msg));
276 root 1.1
277     void
278 root 1.8 UUSetBusyCallback (func = 0,msecs = 1000)
279 root 1.1 SV * func
280     long msecs
281     CODE:
282 root 1.13 UUSetBusyCallback (FUNC_CB (uu_busy), msecs);
283 root 1.1
284     void
285 root 1.8 UUSetFileCallback (func = 0)
286 root 1.1 SV * func
287     CODE:
288 root 1.13 UUSetFileCallback (FUNC_CB (uu_file));
289 root 1.1
290     void
291 root 1.8 UUSetFNameFilter (func = 0)
292 root 1.1 SV * func
293     CODE:
294 root 1.13 UUSetFNameFilter (FUNC_CB (uu_fnamefilter));
295 root 1.1
296 root 1.5 void
297 root 1.8 UUSetFileNameCallback (func = 0)
298 root 1.5 SV * func
299     CODE:
300 root 1.13 UUSetFileNameCallback (FUNC_CB (uu_filename));
301 root 1.5
302 root 1.1 char *
303 root 1.8 UUFNameFilter (fname)
304 root 1.1 char * fname
305    
306     void
307 root 1.11 UULoadFile (fname, id = 0, delflag = 0, partno = -1)
308 root 1.1 char * fname
309     char * id
310     int delflag
311 root 1.11 int partno
312 root 1.1 PPCODE:
313 root 1.16 {
314     int count;
315 root 1.17 IV ret;
316    
317     RELEASE;
318     ret = UULoadFileWithPartNo (fname, id, delflag, partno, &count);
319     ACQUIRE;
320 root 1.16
321 root 1.17 XPUSHs (sv_2mortal (newSViv (ret)));
322 root 1.16 if (GIMME_V == G_ARRAY)
323     XPUSHs (sv_2mortal (newSViv (count)));
324     }
325 root 1.1
326     int
327 root 1.8 UUSmerge (pass)
328 root 1.1 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 root 1.8 UUGetFileListItem (num)
408 root 1.1 int num
409    
410 root 1.18 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 root 1.8 MODULE = Convert::UUlib PACKAGE = Convert::UUlib::Item
417    
418 root 1.1 int
419 root 1.8 rename (item, newname)
420 root 1.1 uulist *item
421     char * newname
422 root 1.8 CODE:
423     RETVAL = UURenameFile (item, newname);
424     OUTPUT:
425     RETVAL
426 root 1.1
427     int
428 root 1.8 decode_temp (item)
429 root 1.1 uulist *item
430 root 1.8 CODE:
431 root 1.17 RELEASE;
432 root 1.8 RETVAL = UUDecodeToTemp (item);
433 root 1.17 ACQUIRE;
434 root 1.8 OUTPUT:
435     RETVAL
436 root 1.1
437     int
438 root 1.8 remove_temp (item)
439 root 1.1 uulist *item
440 root 1.8 CODE:
441 root 1.17 RELEASE;
442 root 1.8 RETVAL = UURemoveTemp (item);
443 root 1.17 ACQUIRE;
444 root 1.8 OUTPUT:
445     RETVAL
446 root 1.1
447     int
448 root 1.8 decode (item, target = 0)
449 root 1.1 uulist *item
450     char * target
451 root 1.8 CODE:
452 root 1.17 RELEASE;
453 root 1.8 RETVAL = UUDecodeFile (item, target);
454 root 1.17 ACQUIRE;
455 root 1.8 OUTPUT:
456     RETVAL
457 root 1.1
458     void
459 root 1.8 info (item, func)
460 root 1.1 uulist *item
461     SV * func
462     CODE:
463 root 1.17 RELEASE;
464     UUInfoFile (item, (void *)func, uu_info_file);
465     ACQUIRE;
466 root 1.1
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 root 1.8 filename (li, newfilename = 0)
504 root 1.1 uulist *li
505     char * newfilename
506     CODE:
507     if (newfilename)
508     {
509 root 1.4 _FP_free (li->filename);
510     li->filename = _FP_strdup (newfilename);
511 root 1.1 }
512     RETVAL = li->filename;
513     OUTPUT:
514     RETVAL
515    
516     char *
517 root 1.8 subfname (li)
518 root 1.1 uulist *li
519     CODE:
520     RETVAL = li->subfname;
521     OUTPUT:
522     RETVAL
523    
524     char *
525 root 1.8 mimeid (li)
526 root 1.1 uulist *li
527     CODE:
528     RETVAL = li->mimeid;
529     OUTPUT:
530     RETVAL
531    
532     char *
533 root 1.8 mimetype (li)
534 root 1.1 uulist *li
535     CODE:
536     RETVAL = li->mimetype;
537     OUTPUT:
538     RETVAL
539    
540     char *
541 root 1.8 binfile (li)
542 root 1.1 uulist *li
543     CODE:
544     RETVAL = li->binfile;
545     OUTPUT:
546     RETVAL
547    
548 root 1.8 # methods accessing internal data(!)
549 root 1.1
550     void
551 root 1.8 parts (li)
552 root 1.1 uulist *li
553     PPCODE:
554 root 1.16 {
555     struct _uufile *p = li->thisfile;
556 root 1.1
557 root 1.16 while (p)
558     {
559     HV *pi = newHV ();
560    
561 root 1.20 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 root 1.16
570     XPUSHs (sv_2mortal (newRV_noinc ((SV *)pi)));
571    
572     p = p->NEXT;
573     }
574     }
575 root 1.1
576     BOOT:
577 root 1.20 {
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 root 1.13 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 root 1.20
656 root 1.19 initialise ();
657 root 1.20 }
658 root 1.1