1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/xml_attached_file.c Thu Nov 16 08:30:26 2006 +0000
1.3 @@ -0,0 +1,144 @@
1.4 +/*
1.5 + * This program converts an attached file (which has previously been
1.6 + * downloaded from sourceforge) into bugzilla-style XML.
1.7 + */
1.8 +
1.9 +#include <stdlib.h>
1.10 +#include <stdio.h>
1.11 +#include <string.h>
1.12 +#ifdef __linux__
1.13 +#include <getopt.h>
1.14 +#endif
1.15 +
1.16 +#ifdef __linux__
1.17 +static struct option long_options[] = {
1.18 + {"type", 1, 0, 't'},
1.19 + {"id", 1, 0, 'i'},
1.20 + {"patch", 0, 0, 'p'},
1.21 + {0, 0, 0, 0}
1.22 +};
1.23 +
1.24 +static char *long_option_str(char opt)
1.25 +{
1.26 + int i;
1.27 + static char buf[100];
1.28 + for(i=0;long_options[i].name;i++)
1.29 + if (long_options[i].val==opt)
1.30 + {
1.31 + sprintf(buf,", --%s",long_options[i].name);
1.32 + return buf;
1.33 + }
1.34 + return "";
1.35 +}
1.36 +#else
1.37 +#define long_option_str(opt) ""
1.38 +#endif
1.39 +
1.40 +usage()
1.41 +{
1.42 + fprintf(stderr,"Usage: xml_attached_file [OPTION] file\n");
1.43 + fprintf(stderr,"\n");
1.44 + fprintf(stderr," -t%s=MIME-type MIME type to use\n",
1.45 + long_option_str('t'));
1.46 + fprintf(stderr," -i%s=ID Attachment ID to use\n",
1.47 + long_option_str('i'));
1.48 + fprintf(stderr," -p%s Mark attachment as a patch\n",
1.49 + long_option_str('p'));
1.50 + exit(1);
1.51 +}
1.52 +
1.53 +/* Note that we limit line lengths to 76 characters following RFC 2045
1.54 + * (bugzilla uses MIME::Base64). This isn't strictly compliant with RFC 4648.
1.55 + */
1.56 +static void base64_encode(FILE *in,FILE *out)
1.57 +{
1.58 + int ng=0; /* 76 characters == 19 groups */
1.59 + size_t nb;
1.60 + unsigned char bytes[3];
1.61 + const char alphabet[64]=
1.62 + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1.63 + while ((nb=fread(bytes,1,3,in))==3)
1.64 + {
1.65 + if (ng++>=19)
1.66 + {
1.67 + putc('\n',out);
1.68 + ng=1;
1.69 + }
1.70 + putc(alphabet[bytes[0]>>2],out);
1.71 + putc(alphabet[(bytes[0]<<4|bytes[1]>>4)&0x3F],out);
1.72 + putc(alphabet[(bytes[1]<<2|bytes[2]>>6)&0x3F],out);
1.73 + putc(alphabet[bytes[2]&0x3F],out);
1.74 + }
1.75 + if (nb)
1.76 + {
1.77 + if (ng>=19)
1.78 + putc('\n',out);
1.79 + putc(alphabet[bytes[0]>>2],out);
1.80 + if (nb==2)
1.81 + {
1.82 + putc(alphabet[(bytes[0]<<4|bytes[1]>>4)&0x3F],out);
1.83 + putc(alphabet[bytes[1]<<2&0x3F],out);
1.84 + }
1.85 + else
1.86 + {
1.87 + putc(alphabet[bytes[0]<<4&0x3F],out);
1.88 + putc('=',out);
1.89 + }
1.90 + putc('=',out);
1.91 + }
1.92 +}
1.93 +
1.94 +int main(int argc,char **argv)
1.95 +{
1.96 + int c;
1.97 + FILE *fp;
1.98 + unsigned long id=0;
1.99 + int ispatch=0;
1.100 + char *type=NULL;
1.101 + for(;;)
1.102 + {
1.103 +#ifdef __linux__
1.104 + int option_index=0;
1.105 + c=getopt_long(argc,argv,"t:i:p",long_options,&option_index);
1.106 +#else
1.107 + c=getopt(argc,argv,"t:i:p");
1.108 +#endif
1.109 + if (c<0)
1.110 + break;
1.111 + switch(c)
1.112 + {
1.113 + case 't':
1.114 + type=optarg;
1.115 + break;
1.116 + case 'i':
1.117 + id=strtoul(optarg,NULL,10);
1.118 + break;
1.119 + case 'p':
1.120 + ispatch=1;
1.121 + break;
1.122 + default:
1.123 + usage();
1.124 + }
1.125 + }
1.126 + if (optind<argc)
1.127 + {
1.128 + fp=fopen(argv[optind],"rb");
1.129 + if (!fp)
1.130 + {
1.131 + perror(argv[optind]);
1.132 + exit(1);
1.133 + }
1.134 + }
1.135 + else
1.136 + fp=stdin;
1.137 + printf("<attachment ispatch=\"%d\">\n",ispatch);
1.138 + if (id)
1.139 + printf(" <attachid>%lu</attachid>\n",id);
1.140 + if (type)
1.141 + printf(" <type>%s</type>\n",type);
1.142 + printf(" <data encoding=\"base64\">\n");
1.143 + base64_encode(fp,stdout);
1.144 + printf("\n </data>\n");
1.145 + printf("</attachment>\n");
1.146 + exit(0);
1.147 +}