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