xml_attached_file.c
changeset 0 ae7b3fa753dc
     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 +}