Example #1
0
/*
 * find the best alternative part.
 *
 * turkeys have started emitting empty text/plain parts,
 * with the actual content in a text/html part, which complicates the choice.
 *
 * bigger turkeys emit a tiny base64-encoded text/plain part,
 * a small base64-encoded text/html part, and the real content is in
 * a text/calendar part.
 *
 * the magic lengths are empirically derived.
 * as turkeys devolve and mutate, this will only get worse.
 */
static Message*
bestalt(Message *m, char *dir)
{
	int len;
	char *subdir;
	Message *nm;
	Message *realplain, *realhtml, *realcal;

	realplain = realhtml = realcal = nil;
	for(nm = m->head; nm != nil; nm = nm->next){
		subdir = estrstrdup(dir, nm->name);
		len = 0;
		free(readbody(nm->type, subdir, &len));
		free(subdir);
		if(strcmp(nm->type, "text/plain") == 0 && len >= 8)
			realplain = nm;
		else if(strcmp(nm->type, "text/html") == 0 && len >= 600)
			realhtml = nm;
		else if(strcmp(nm->type, "text/calendar") == 0)
			realcal = nm;
	}
	if(realplain == nil && realhtml == nil && realcal)
		return realcal;			/* super-turkey */
	else if(realplain == nil && realhtml)
		return realhtml;		/* regular turkey */
	else
		return realplain;
}
Example #2
0
int
quote(Message *m, CFid *fid, char *dir, char *quotetext)
{
	char *body, *type;
	int i, n, nlines;
	char **lines;

	if(quotetext){
		body = quotetext;
		n = strlen(body);
		type = nil;
	}else{
		/* look for first textual component to quote */
		type = readfile(dir, "type", &n);
		if(type == nil){
			print("no type in %s\n", dir);
			return 0;
		}
		if(strncmp(type, "multipart/", 10)==0 || strncmp(type, "message/", 8)==0){
			dir = estrstrdup(dir, "1/");
			if(quote(m, fid, dir, nil)){
				free(type);
				free(dir);
				return 1;
			}
			free(dir);
		}
		if(strncmp(type, "text", 4) != 0){
			free(type);
			return 0;
		}
		body = readbody(m->type, dir, &n);
		if(body == nil)
			return 0;
	}
	nlines = 0;
	for(i=0; i<n; i++)
		if(body[i] == '\n')
			nlines++;
	nlines++;
	lines = emalloc(nlines*sizeof(char*));
	nlines = getfields(body, lines, nlines, 0, "\n");
	/* delete leading and trailing blank lines */
	i = 0;
	while(i<nlines && lines[i][0]=='\0')
		i++;
	while(i<nlines && lines[nlines-1][0]=='\0')
		nlines--;
	while(i < nlines){
		fsprint(fid, ">%s%s\n", lines[i][0]=='>'? "" : " ", lines[i]);
		i++;
	}
	free(lines);
	free(body);	/* will free quotetext if non-nil */
	free(type);
	return 1;
}
Example #3
0
void
mesgload(Message *m, char *rootdir, char *file, Window *w)
{
	char *s, *subdir, *name, *dir;
	Message *mp, *thisone;
	int n;

	dir = estrstrdup(rootdir, file);

	if(strcmp(m->type, "message/rfc822") != 0){	/* suppress headers of envelopes */
		if(strlen(m->from) > 0){
			Bprint(w->body, "From: %s\n", m->from);
			mesgline(m, "Date", m->date);
			mesgline(m, "To", m->to);
			mesgline(m, "CC", m->cc);
			mesgline(m, "Subject", m->subject);
			printheader(dir, w->body, extraheaders);
		}else{
			printheader(dir, w->body, okheaders);
			printheader(dir, w->body, extraheaders);
		}
		Bprint(w->body, "\n");
	}

	if(m->level == 1 && m->recursed == 0){
		m->recursed = 1;
		readmbox(m, rootdir, m->name);
	}
	if(m->head == nil){	/* single part message */
		if(strcmp(m->type, "text")==0 || strncmp(m->type, "text/", 5)==0){
			mimedisplay(m, m->name, rootdir, w, 1);
			s = readbody(m->type, dir, &n);
			winwritebody(w, s, n);
			free(s);
		}else
			mimedisplay(m, m->name, rootdir, w, 0);
	}else{
		/* multi-part message, either multipart or message/rfc822 */
		thisone = nil;
		if(strcmp(m->type, "multipart/alternative") == 0){
			thisone = bestalt(m, dir);
			if(thisone == nil){
				thisone = m->head; /* in case we can't find a good one */
				for(mp=m->head; mp!=nil; mp=mp->next)
					if(isprintable(mp->type)){
						thisone = mp;
						break;
					}
			}
		}
		for(mp=m->head; mp!=nil; mp=mp->next){
			if(thisone!=nil && mp!=thisone)
				continue;
			subdir = estrstrdup(dir, mp->name);
			name = estrstrdup(file, mp->name);
			/* skip first element in name because it's already in window name */
			if(mp != m->head)
				Bprint(w->body, "\n===> %s (%s) [%s]\n",
					strchr(name, '/')+1, mp->type,
					mp->disposition);
			if(strcmp(mp->type, "text")==0 ||
			    strncmp(mp->type, "text/", 5)==0){
				mimedisplay(mp, name, rootdir, w, 1);
				printheader(subdir, w->body, okheaders);
				printheader(subdir, w->body, extraheaders);
				winwritebody(w, "\n", 1);
				s = readbody(mp->type, subdir, &n);
				winwritebody(w, s, n);
				free(s);
			}else{
				if(strncmp(mp->type, "multipart/", 10)==0 ||
				    strcmp(mp->type, "message/rfc822")==0){
					mp->w = w;
					mesgload(mp, rootdir, name, w);
					mp->w = nil;
				}else
					mimedisplay(mp, name, rootdir, w, 0);
			}
			free(name);
			free(subdir);
		}
	}
	free(dir);
}
Example #4
0
int main (int argc, char *argv[])
{
  int use_stdin = 0;
  FILE *newsfile;
  FILE *newsfile_copy;
  char *bodyfile_name = NULL;
  FILE *bodyfile_r;
  FILE *bodyfile_w;
  char *mergefile_name = NULL;
  FILE *mergefile;

#if defined(MAINLOOP)
  volatile int w = 1;
  while (w);
#endif

  parse_commandline (argc, argv);

  if (printversion)
  {
    printf ("%s (" PACKAGE ") " VERSION "\n", Name);
    return 0;
  }

  if (!strcmp (newsfile_name, "-"))
  {
    use_stdin = 1;
    newsfile_name = nb_tmpnam ();
    newsfile_copy = open_write (newsfile_name);
    newsfile = stdin;

    mergefile = stdout;
  }
  else
  {
    newsfile_copy = NULL;
    newsfile = open_read (newsfile_name);

    mergefile_name = nb_tmpnam ();
    mergefile = open_write (mergefile_name);
  }

  if (filter)
  {
    expand_argv (new_argv, "-");
    exec_filter (new_argv, &bodyfile_w, &bodyfile_r);
    writebody (newsfile, newsfile_copy, bodyfile_w,
	       remove_header, remove_quote, remove_sig, keep);

    newsfile = open_read (newsfile_name);
    readbody (newsfile, bodyfile_r, mergefile,
	      remove_header, remove_quote, remove_sig, keep);
    check_child ();
  }
  else
  {
    bodyfile_name = nb_tmpnam ();
    bodyfile_w = open_write (bodyfile_name);
    expand_argv (new_argv, bodyfile_name);
    writebody (newsfile, newsfile_copy, bodyfile_w,
	       remove_header, remove_quote, remove_sig, keep);

    exec_program (new_argv);
    check_child ();

    newsfile = open_read (newsfile_name);
    bodyfile_r = open_read (bodyfile_name);
    readbody (newsfile, bodyfile_r, mergefile,
	      remove_header, remove_quote, remove_sig, keep);
  }

  if (use_stdin)
    nb_unlink (newsfile_name);
  else
    nb_rename (mergefile_name, newsfile_name);

  if (!filter)
    nb_unlink (bodyfile_name);

  return 0;
}