ali@0: /* ali@0: * This program converts an attached file (which has previously been ali@0: * downloaded from sourceforge) into bugzilla-style XML. ali@0: */ ali@0: ali@0: #include ali@0: #include ali@0: #include ali@0: #ifdef __linux__ ali@0: #include ali@0: #endif ali@0: ali@0: #ifdef __linux__ ali@0: static struct option long_options[] = { ali@0: {"type", 1, 0, 't'}, ali@0: {"id", 1, 0, 'i'}, ali@0: {"patch", 0, 0, 'p'}, ali@0: {0, 0, 0, 0} ali@0: }; ali@0: ali@0: static char *long_option_str(char opt) ali@0: { ali@0: int i; ali@0: static char buf[100]; ali@0: for(i=0;long_options[i].name;i++) ali@0: if (long_options[i].val==opt) ali@0: { ali@0: sprintf(buf,", --%s",long_options[i].name); ali@0: return buf; ali@0: } ali@0: return ""; ali@0: } ali@0: #else ali@0: #define long_option_str(opt) "" ali@0: #endif ali@0: ali@0: usage() ali@0: { ali@0: fprintf(stderr,"Usage: xml_attached_file [OPTION] file\n"); ali@0: fprintf(stderr,"\n"); ali@0: fprintf(stderr," -t%s=MIME-type MIME type to use\n", ali@0: long_option_str('t')); ali@0: fprintf(stderr," -i%s=ID Attachment ID to use\n", ali@0: long_option_str('i')); ali@0: fprintf(stderr," -p%s Mark attachment as a patch\n", ali@0: long_option_str('p')); ali@0: exit(1); ali@0: } ali@0: ali@0: /* Note that we limit line lengths to 76 characters following RFC 2045 ali@0: * (bugzilla uses MIME::Base64). This isn't strictly compliant with RFC 4648. ali@0: */ ali@0: static void base64_encode(FILE *in,FILE *out) ali@0: { ali@0: int ng=0; /* 76 characters == 19 groups */ ali@0: size_t nb; ali@0: unsigned char bytes[3]; ali@0: const char alphabet[64]= ali@0: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ali@0: while ((nb=fread(bytes,1,3,in))==3) ali@0: { ali@0: if (ng++>=19) ali@0: { ali@0: putc('\n',out); ali@0: ng=1; ali@0: } ali@0: putc(alphabet[bytes[0]>>2],out); ali@0: putc(alphabet[(bytes[0]<<4|bytes[1]>>4)&0x3F],out); ali@0: putc(alphabet[(bytes[1]<<2|bytes[2]>>6)&0x3F],out); ali@0: putc(alphabet[bytes[2]&0x3F],out); ali@0: } ali@0: if (nb) ali@0: { ali@0: if (ng>=19) ali@0: putc('\n',out); ali@0: putc(alphabet[bytes[0]>>2],out); ali@0: if (nb==2) ali@0: { ali@0: putc(alphabet[(bytes[0]<<4|bytes[1]>>4)&0x3F],out); ali@0: putc(alphabet[bytes[1]<<2&0x3F],out); ali@0: } ali@0: else ali@0: { ali@0: putc(alphabet[bytes[0]<<4&0x3F],out); ali@0: putc('=',out); ali@0: } ali@0: putc('=',out); ali@0: } ali@0: } ali@0: ali@0: int main(int argc,char **argv) ali@0: { ali@0: int c; ali@0: FILE *fp; ali@0: unsigned long id=0; ali@0: int ispatch=0; ali@0: char *type=NULL; ali@0: for(;;) ali@0: { ali@0: #ifdef __linux__ ali@0: int option_index=0; ali@0: c=getopt_long(argc,argv,"t:i:p",long_options,&option_index); ali@0: #else ali@0: c=getopt(argc,argv,"t:i:p"); ali@0: #endif ali@0: if (c<0) ali@0: break; ali@0: switch(c) ali@0: { ali@0: case 't': ali@0: type=optarg; ali@0: break; ali@0: case 'i': ali@0: id=strtoul(optarg,NULL,10); ali@0: break; ali@0: case 'p': ali@0: ispatch=1; ali@0: break; ali@0: default: ali@0: usage(); ali@0: } ali@0: } ali@0: if (optind\n",ispatch); ali@0: if (id) ali@0: printf(" %lu\n",id); ali@0: if (type) ali@0: printf(" %s\n",type); ali@0: printf(" \n"); ali@0: base64_encode(fp,stdout); ali@0: printf("\n \n"); ali@0: printf("\n"); ali@0: exit(0); ali@0: }