static char * imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, va_list ap) { GPtrArray *args; const char *p, *start; char *out, *outptr, *string; int num, len, i, arglen; args = g_ptr_array_new (); /* Determine the length of the data */ len = strlen (fmt); p = start = fmt; while (*p) { p = strchr (start, '%'); if (!p) break; switch (*++p) { case 'd': num = va_arg (ap, int); g_ptr_array_add (args, GINT_TO_POINTER (num)); start = p + 1; len += 10; break; case 's': string = va_arg (ap, char *); g_ptr_array_add (args, string); start = p + 1; len += strlen (string); break; case 'S': case 'F': case 'G': string = va_arg (ap, char *); /* NB: string is freed during output for %F and %G */ if (*p == 'F') { char *s = camel_imap_store_summary_full_from_path(store->summary, string); if (s) { string = camel_utf8_utf7(s); g_free(s); } else { string = camel_utf8_utf7(string); } } else if (*p == 'G') { string = camel_utf8_utf7(string); } arglen = strlen (string); g_ptr_array_add (args, string); if (imap_is_atom (string)) { len += arglen; } else { if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) len += arglen + 15; else len += arglen * 2; } start = p + 1; break; case '%': start = p; break; default: g_warning ("camel-imap-command is not printf. I don't " "know what '%%%c' means.", *p); start = *p ? p + 1 : p; break; } } /* Now write out the string */ outptr = out = g_malloc (len + 1); p = start = fmt; i = 0; while (*p) { p = strchr (start, '%'); if (!p) { strcpy (outptr, start); break; } else { strncpy (outptr, start, p - start); outptr += p - start; } switch (*++p) { case 'd': num = GPOINTER_TO_INT (args->pdata[i++]); outptr += sprintf (outptr, "%d", num); break; case 's': string = args->pdata[i++]; outptr += sprintf (outptr, "%s", string); break; case 'S': case 'F': case 'G': string = args->pdata[i++]; if (imap_is_atom (string)) { outptr += sprintf (outptr, "%s", string); } else { len = strlen (string); if (len && store->capabilities & IMAP_CAPABILITY_LITERALPLUS) { outptr += sprintf (outptr, "{%d+}\r\n%s", len, string); } else { char *quoted = imap_quote_string (string); outptr += sprintf (outptr, "%s", quoted); g_free (quoted); } } if (*p == 'F' || *p == 'G') g_free (string); break; default: *outptr++ = '%'; *outptr++ = *p; } start = *p ? p + 1 : p; } g_ptr_array_free (args, TRUE); return out; }
char * camel_nntp_store_summary_path_to_full (CamelNNTPStoreSummary *s, const char *path, char dir_sep) { char *full, *f; guint32 c, v = 0; const char *p; int state=0; char *subpath, *last = NULL; CamelStoreInfo *si; /* check to see if we have a subpath of path already defined */ subpath = g_alloca (strlen (path) + 1); strcpy (subpath, path); do { si = camel_store_summary_path ((CamelStoreSummary *) s, subpath); if (si == NULL) { last = strrchr (subpath, '/'); if (last) *last = 0; } } while (si == NULL && last); /* path is already present, use the raw version we have */ if (si && strlen (subpath) == strlen (path)) { f = g_strdup (camel_nntp_store_info_full_name (s, si)); camel_store_summary_info_free ((CamelStoreSummary *) s, si); return f; } f = full = g_alloca (strlen (path)*2+1); if (si) p = path + strlen (subpath); else p = path; while ((c = camel_utf8_getc ((const unsigned char **) &p))) { switch (state) { case 0: if (c == '%') { state = 1; } else { if (c == '/') c = dir_sep; camel_utf8_putc((unsigned char **) &f, c); } break; case 1: state = 2; v = hexnib (c) << 4; break; case 2: state = 0; v |= hexnib (c); camel_utf8_putc ((unsigned char **) &f, v); break; } } camel_utf8_putc ((unsigned char **) &f, c); /* merge old path part if required */ f = camel_utf8_utf7 (full); if (si) { full = g_strdup_printf ("%s%s", camel_nntp_store_info_full_name (s, si), f); g_free (f); camel_store_summary_info_free ((CamelStoreSummary *) s, si); f = full; } return f; }