aboutsummaryrefslogtreecommitdiffstats
path: root/g10/photoid.c
diff options
context:
space:
mode:
Diffstat (limited to 'g10/photoid.c')
-rw-r--r--g10/photoid.c116
1 files changed, 99 insertions, 17 deletions
diff --git a/g10/photoid.c b/g10/photoid.c
index 27ad7fe95..3953e6dbe 100644
--- a/g10/photoid.c
+++ b/g10/photoid.c
@@ -116,7 +116,7 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
parse_attribute_subpkts(uid);
make_attribute_uidname(uid);
- show_photo(uid->attribs,pk);
+ show_photos(uid->attribs,uid->numattribs,pk);
switch(cpr_get_answer_yes_no_quit("photoid.jpeg.okay",
_("Is this photo correct (y/N/q)? ")))
{
@@ -147,31 +147,113 @@ PKT_user_id *generate_photo_id(PKT_public_key *pk)
return uid;
}
-void show_photo(const struct user_attribute *attr,PKT_public_key *pk)
+/* Returns 0 for error, 1 for valid */
+int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
{
- char *command;
- struct exec_info *spawn;
+ int headerlen;
- /* make command grow */
- command=
- pct_expando(opt.photo_viewer?opt.photo_viewer:DEFAULT_PHOTO_COMMAND,pk);
+ if(attr->len<3)
+ return 0;
- if(!command)
- goto fail;
+ /* For historical reasons (i.e. "oops!"), the header length is
+ little endian. */
+ headerlen=(attr->data[1]<<8) | attr->data[0];
- if(exec_write(&spawn,NULL,command,1,1)!=0)
- goto fail;
+ if(headerlen>attr->len)
+ return 0;
- fwrite(attr->data,attr->len,1,spawn->tochild);
+ if(type && attr->len>=4)
+ {
+ if(attr->data[2]==1) /* header version 1 */
+ *type=attr->data[3];
+ else
+ *type=0;
+ }
+
+ *len=attr->len-headerlen;
+
+ if(*len==0)
+ return 0;
+
+ return 1;
+}
- if(exec_read(spawn)!=0)
+/* style==0 for extension, 1 for name, 2 for MIME type. Remember that
+ the "name" style string could be used in a user ID name field, so
+ make sure it is not too big (see
+ parse-packet.c:parse_attribute). */
+char *image_type_to_string(byte type,int style)
+{
+ char *string;
+
+ switch(type)
{
- exec_finish(spawn);
- goto fail;
+ case 1: /* jpeg */
+ if(style==0)
+ string="jpg";
+ else if(style==1)
+ string="jpeg";
+ else
+ string="image/jpeg";
+ break;
+
+ default:
+ if(style==0)
+ string="bin";
+ else if(style==1)
+ string="unknown";
+ else
+ string="image/x-unknown";
+ break;
}
- if(exec_finish(spawn)!=0)
- goto fail;
+ return string;
+}
+
+void show_photos(const struct user_attribute *attrs,
+ int count,PKT_public_key *pk)
+{
+ int i;
+ struct expando_args args;
+ u32 len;
+
+ memset(&args,0,sizeof(args));
+ args.pk=pk;
+
+ for(i=0;i<count;i++)
+ if(attrs[i].type==ATTRIB_IMAGE &&
+ parse_image_header(&attrs[i],&args.imagetype,&len))
+ {
+ char *command;
+ struct exec_info *spawn;
+ int offset=attrs[i].len-len;
+
+ /* Notice we are not using the byte for image encoding type
+ for more than cosmetics. Most external image viewers can
+ handle a multitude of types, and even if one cannot
+ understand a partcular type, we have no way to know which.
+ The spec specifically permits this, by the way. -dms */
+
+ /* make command grow */
+ command=pct_expando(opt.photo_viewer?
+ opt.photo_viewer:DEFAULT_PHOTO_COMMAND,&args);
+ if(!command)
+ goto fail;
+
+ if(exec_write(&spawn,NULL,command,1,1)!=0)
+ goto fail;
+
+ fwrite(&attrs[i].data[offset],attrs[i].len-offset,1,spawn->tochild);
+
+ if(exec_read(spawn)!=0)
+ {
+ exec_finish(spawn);
+ goto fail;
+ }
+
+ if(exec_finish(spawn)!=0)
+ goto fail;
+ }
return;