[Libpst-devel] Re: PATCH: readpst.c code reorganisation

Arne Ahrend aahrend at web.de
Sun Feb 19 19:38:57 UTC 2006


On Sun, 19 Feb 2006 20:33:56 +0100
Arne Ahrend <aahrend at web.de> wrote:

Fourth patch

> This is a series of patches succesively taking chunks of code out of 
> the huge main() function in readpst.c and into separate functions.
> 
> No functionality change, but improvement of readability.
> 
> Arne

--- readpst.c-03	2006-02-19 19:22:54.000000000 +0100
+++ readpst.c	2006-02-19 19:53:08.000000000 +0100
@@ -90,6 +90,7 @@ void write_separate_attachment(char f_na
 void write_inline_attachment(FILE* f_output, pst_item_attach* current_attach, char boundary[], pst_file* pst);
 void write_fabricated_header(FILE* f_output, pst_item_email* email, pst_item_attach* attach,
 			     char boundary[], int mode, char c_time[], time_t em_time);
+void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, pst_file* pst);
 // }}}1
 // Global Variables {{{1
 char *prog_name; 
@@ -138,18 +139,14 @@ int main(int argc, char** argv) {
   pst_file pstfile;
   pst_desc_ll *d_ptr;
   char * fname = NULL;
-  time_t em_time;
-  char * c_time, *d_log=NULL;
+  char *d_log=NULL;
   int c,x;
   int mode = MODE_NORMAL;
   int output_mode = OUTPUT_NORMAL;
   int contact_mode = CMODE_VCARD;
   int overwrite = 0;
-  int base64_body = 0;
   //  int encrypt = 0;
-  char *boundary = NULL, *b1, *b2; // the boundary marker between multipart sections
   char *temp = NULL; //temporary char pointer
-  int attach_num = 0;
   int skip_child = 0;
   struct file_ll  *f, *head;
   prog_name = argv[0];
@@ -589,223 +586,7 @@ int main(int argc, char** argv) {
 	f->email_count++;
 
 	DEBUG_MAIN(("main: seen an email\n"));
-
-	// convert the sent date if it exists, or set it to a fixed date
-	if (item->email->sent_date != NULL) {
-	  em_time = fileTimeToUnixTime(item->email->sent_date, 0);
-	  c_time = ctime(&em_time);
-	  if (c_time != NULL)
-	    c_time[strlen(c_time)-1] = '\0'; //remove end \n
-	  else
-	    c_time = "Fri Dec 28 12:06:21 2001";
-	} else
-	  c_time= "Fri Dec 28 12:06:21 2001";
-
-	// if the boundary is still set from the previous run, then free it
-	if (boundary != NULL) {
-	  free (boundary);
-	  boundary = NULL;
-	}
-
-	// we will always look at the header to discover some stuff
-	if (item->email->header != NULL ) {
-	  // see if there is a boundary variable there
-	  // this search MUST be made case insensitive (DONE).
-	  // Also, some check to find out if we
-	  // are looking at the boundary associated with content-type, and that the content
-	  // type really is "multipart"
-	  if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) {
-	    b2 += strlen("boundary="); // move boundary to first char of marker
-	    
-	    if (*b2 == '"') {
-	      b2++;
-	      b1 = strchr(b2, '"'); // find terminating quote
-	    } else {
-	      b1 = b2;
-	      while (isgraph(*b1)) // find first char that isn't part of boundary
-		b1++;
-	    }
-	    
-	    boundary = malloc ((b1-b2)+1); //malloc that length
-	    memset (boundary, 0, (b1-b2)+1);  // blank it
-	    strncpy(boundary, b2, b1-b2); // copy boundary to another variable
-	    b1 = b2 = boundary;
-	    while (*b2 != '\0') { // remove any CRs and Tabs
-	      if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') {
-		*b1 = *b2;
-		b1++;
-	      }
-	      b2++;
-	    }
-	    *b1 = '\0';
-	    
-	    DEBUG_MAIN(("main: Found boundary of - %s\n", boundary));
-	  } else {
-
-	    DEBUG_MAIN(("main: boundary not found in header\n"));
-	  }
-
-	  // also possible to set 7bit encoding detection here.
-	  if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) {
-	    if ((b2 = strchr(b2, ':')) != NULL) {
-	      b2++; // skip to the : at the end of the string
-		
-	      while (*b2 == ' ' || *b2 == '\t')
-		b2++;
-	      if (pst_strincmp(b2, "base64", 6)==0) {
-		DEBUG_MAIN(("body is base64 encoded\n"));
-		base64_body = 1;
-	      }
-	    } else {
-	      DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n"));
-	    }
-	  }
-	    
-	}
-	if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody)
-				 || item->email->rtf_compressed || item->email->encrypted_body
-				 || item->email->encrypted_htmlbody)) {
-	  // we need to create a boundary here.
-	  DEBUG_EMAIL(("main: must create own boundary. oh dear.\n"));
-	  boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary
-	  boundary[0] = '\0';
-	  sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand());
-	  DEBUG_EMAIL(("main: created boundary is %s\n", boundary));
-	}
-
-	DEBUG_MAIN(("main: About to print Header\n"));
-
-	if (item != NULL && item->email != NULL && item->email->subject != NULL &&
-	    item->email->subject->subj != NULL) {
-	  DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj));
-	}
-	if (item->email->header != NULL) {
-	  // some of the headers we get from the file are not properly defined.
-	  // they can contain some email stuff too. We will cut off the header
-	  // when we see a \n\n or \r\n\r\n
-
-	  removeCR(item->email->header);
-
-	  temp = strstr(item->email->header, "\n\n");
-
-	  if (temp != NULL) {
-	    DEBUG_MAIN(("main: Found body text in header\n"));
-	    temp += 2; // get past the \n\n
-	    *temp = '\0';
-	  }
-	  
-	  if (mode != MODE_SEPERATE) {
-	    char *soh = NULL;  // real start of headers.
-	    // don't put rubbish in if we are doing seperate
-	    fprintf(f->output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time);
-	    soh = skip_header_prologue(item->email->header);
-	    fprintf(f->output, "%s\n\n", soh);
-	  } else {
-	    fprintf(f->output, "%s\n", item->email->header);
-	  }
-	} else
-	  write_fabricated_header(f->output, item->email, item->attach, boundary, mode, c_time, em_time);
-	
-
-	DEBUG_MAIN(("main: About to print Body\n"));
-
-	if (item->email->body != NULL) {
-	  if (boundary) {
-	    fprintf(f->output, "\n--%s\n", boundary);
-	    fprintf(f->output, "Content-type: text/plain\n\n");
-	    if (base64_body)
-	      fprintf(f->output, "Content-Transfer-Encoding: base64\n");
-	  }
-	  removeCR(item->email->body);
-	  if (base64_body)
-	    write_email_body(f->output, base64_encode(item->email->body,
-						      strlen(item->email->body)));
-	  else
-	    write_email_body(f->output, item->email->body);
-	}
-	
-	if (item->email->htmlbody != NULL) {
-	  if (boundary) {
-	    fprintf(f->output, "\n--%s\n", boundary);
-	    fprintf(f->output, "Content-type: text/html\n\n");
-	    if (base64_body)
-	      fprintf(f->output, "Content-Transfer-Encoding: base64\n");
-	  }
-	  removeCR(item->email->htmlbody);
-	  if (base64_body)
-	    write_email_body(f->output, base64_encode(item->email->htmlbody,
-						      strlen(item->email->htmlbody)));
-	  else
-	    write_email_body(f->output, item->email->htmlbody);
-	}
-
-	attach_num = 0;
-
-	if (item->email->rtf_compressed != NULL) {
-	  DEBUG_MAIN(("Adding RTF body as attachment\n"));
-	  item->current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach));
-	  memset(item->current_attach, 0, sizeof(pst_item_attach));
-	  item->current_attach->next = item->attach;
-	  item->attach = item->current_attach;
-	  item->current_attach->data = lzfu_decompress(item->email->rtf_compressed);
-	  item->current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2);
-	  strcpy(item->current_attach->filename2, RTF_ATTACH_NAME);
-	  item->current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2);
-	  strcpy(item->current_attach->mimetype, RTF_ATTACH_TYPE);
-	  memcpy(&(item->current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t));
-	  LE32_CPU(item->current_attach->size);
-	  //	  item->email->rtf_compressed = ;
-	  //	  attach_num++;
-	}
-	if (item->email->encrypted_body || item->email->encrypted_htmlbody) {
-	  // if either the body or htmlbody is encrypted, add them as attachments
-	  if (item->email->encrypted_body) {
-	    DEBUG_MAIN(("Adding Encrypted Body as attachment\n"));
-	    item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
-	    memset(item->current_attach, 0, sizeof(pst_item_attach));
-	    item->current_attach->next = item->attach;
-	    item->attach = item->current_attach;
-	    
-	    item->current_attach->data = item->email->encrypted_body;
-	    item->current_attach->size = item->email->encrypted_body_size;
-	    item->email->encrypted_body = NULL;
-	  }
-	  if (item->email->encrypted_htmlbody) {
-	    DEBUG_MAIN(("Adding encrypted HTML body as attachment\n"));
-	    item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
-	    memset(item->current_attach, 0, sizeof(pst_item_attach));
-	    item->current_attach->next = item->attach;
-	    item->attach = item->current_attach;
-
-	    item->current_attach->data = item->email->encrypted_htmlbody;
-	    item->current_attach->size = item->email->encrypted_htmlbody_size;
-	    item->email->encrypted_htmlbody = NULL;
-	  }
-	  write_email_body(f->output, "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n");
-	}
-	base64_body = 0;
-	// attachments
-	for(item->current_attach = item->attach;
-	    item->current_attach;
-	    item->current_attach = item->current_attach->next) {
-	  DEBUG_MAIN(("main: Attempting Attachment encoding\n"));
-	  if (item->current_attach->data == NULL) {
-	    DEBUG_MAIN(("main: Data of attachment is NULL!. Size is supposed to be %i\n", item->current_attach->size));
-	  }
-	  if (mode == MODE_SEPERATE) {
-	    write_separate_attachment(f->name, item->current_attach, attach_num, &pstfile);
-	  } else {
-	    write_inline_attachment(f->output, item->current_attach, boundary, &pstfile);
-	  }
-	  attach_num++;
-	}
-	if (mode != MODE_SEPERATE) {
-	  DEBUG_MAIN(("main: Writing buffer between emails\n"));
-	  if (boundary)
-	    fprintf(f->output, "\n--%s--\n", boundary);
-	  fprintf(f->output, "\n\n");
-	}
-	// }}}2
+	write_normal_email(f->output, f->name, item, mode, &pstfile);
       } else if (item->type == PST_TYPE_JOURNAL) {
 	// Process Journal item {{{2
 	// deal with journal items
@@ -910,10 +691,6 @@ int main(int argc, char** argv) {
     }
 
     DEBUG_MAIN(("main: Going to next d_ptr\n"));
-    if (boundary) {
-      free(boundary);
-      boundary = NULL;
-    }
 
   check_parent:
     //    _pst_freeItem(item);
@@ -1524,3 +1301,224 @@ void write_fabricated_header(FILE* f_out
 	fprintf(f_output, "\n");
 }
 
+void write_normal_email(FILE* f_output, char f_name[], pst_item* item, int mode, pst_file* pst)
+{
+	char *boundary = NULL; // the boundary marker between multipart sections
+	char *c_time;
+	int attach_num = 0, base64_body = 0;
+	time_t em_time;
+	// convert the sent date if it exists, or set it to a fixed date
+	if (item->email->sent_date != NULL) {
+		em_time = fileTimeToUnixTime(item->email->sent_date, 0);
+		c_time = ctime(&em_time);
+		if (c_time != NULL)
+			c_time[strlen(c_time)-1] = '\0'; //remove end \n
+		else
+			c_time = "Fri Dec 28 12:06:21 2001";
+	} else
+		c_time= "Fri Dec 28 12:06:21 2001";
+
+	// we will always look at the header to discover some stuff
+	if (item->email->header != NULL ) {
+		char *b1, *b2;
+		// see if there is a boundary variable there
+		// this search MUST be made case insensitive (DONE).
+		// Also, some check to find out if we
+		// are looking at the boundary associated with content-type, and that the content
+		// type really is "multipart"
+		if ((b2 = my_stristr(item->email->header, "boundary=")) != NULL) {
+			b2 += strlen("boundary="); // move boundary to first char of marker
+	    
+			if (*b2 == '"') {
+				b2++;
+				b1 = strchr(b2, '"'); // find terminating quote
+			} else {
+				b1 = b2;
+				while (isgraph(*b1)) // find first char that isn't part of boundary
+					b1++;
+			}
+	    
+			boundary = malloc ((b1-b2)+1); //malloc that length
+			memset (boundary, 0, (b1-b2)+1);  // blank it
+			strncpy(boundary, b2, b1-b2); // copy boundary to another variable
+			b1 = b2 = boundary;
+			while (*b2 != '\0') { // remove any CRs and Tabs
+				if (*b2 != '\n' && *b2 != '\r' && *b2 != '\t') {
+					*b1 = *b2;
+					b1++;
+				}
+				b2++;
+			}
+			*b1 = '\0';
+	    
+			DEBUG_MAIN(("main: Found boundary of - %s\n", boundary));
+		} else {
+
+			DEBUG_MAIN(("main: boundary not found in header\n"));
+		}
+
+		// also possible to set 7bit encoding detection here.
+		if ((b2 = my_stristr(item->email->header, "Content-Transfer-Encoding:")) != NULL) {
+			if ((b2 = strchr(b2, ':')) != NULL) {
+				b2++; // skip to the : at the end of the string
+		
+				while (*b2 == ' ' || *b2 == '\t')
+					b2++;
+				if (pst_strincmp(b2, "base64", 6)==0) {
+					DEBUG_MAIN(("body is base64 encoded\n"));
+					base64_body = 1;
+				}
+			} else {
+				DEBUG_WARN(("found a ':' during the my_stristr, but not after that..\n"));
+			}
+		}
+	    
+	}
+	if (boundary == NULL && (item->attach ||(item->email->body && item->email->htmlbody)
+				 || item->email->rtf_compressed || item->email->encrypted_body
+				 || item->email->encrypted_htmlbody)) {
+		// we need to create a boundary here.
+		DEBUG_EMAIL(("main: must create own boundary. oh dear.\n"));
+		boundary = malloc(50 * sizeof(char)); // allow 50 chars for boundary
+		if(boundary == NULL)
+			DIE(("write_normal_email: Cannot allocate memory for boundary\n"));
+		boundary[0] = '\0';
+		sprintf(boundary, "--boundary-LibPST-iamunique-%i_-_-", rand());
+		DEBUG_EMAIL(("main: created boundary is %s\n", boundary));
+		/* DO DO: Add our boundary to PST header, if item->email->header != NULL */
+	}
+
+	DEBUG_MAIN(("main: About to print Header\n"));
+
+	if (item != NULL && item->email != NULL && item->email->subject != NULL &&
+	    item->email->subject->subj != NULL) {
+		DEBUG_EMAIL(("item->email->subject->subj = %p\n", item->email->subject->subj));
+	}
+	if (item->email->header != NULL) {
+		char *temp = NULL;
+		// some of the headers we get from the file are not properly defined.
+		// they can contain some email stuff too. We will cut off the header
+		// when we see a \n\n or \r\n\r\n
+
+		removeCR(item->email->header);
+
+		temp = strstr(item->email->header, "\n\n");
+
+		if (temp != NULL) {
+			DEBUG_MAIN(("main: Found body text in header\n"));
+			temp += 2; // get past the \n\n
+			*temp = '\0';
+		}
+	  
+		if (mode != MODE_SEPERATE) {
+			char *soh = NULL;  // real start of headers.
+			// don't put rubbish in if we are doing seperate
+			fprintf(f_output, "From \"%s\" %s\n", item->email->outlook_sender_name, c_time);
+			soh = skip_header_prologue(item->email->header);
+			fprintf(f_output, "%s\n\n", soh);
+		} else {
+			fprintf(f_output, "%s\n", item->email->header);
+		}
+	} else
+		write_fabricated_header(f_output, item->email, item->attach, boundary, mode, c_time, em_time);
+	
+
+	DEBUG_MAIN(("main: About to print Body\n"));
+
+	if (item->email->body != NULL) {
+		if (boundary) {
+			fprintf(f_output, "\n--%s\n", boundary);
+			fprintf(f_output, "Content-type: text/plain\n\n");
+			if (base64_body)
+				fprintf(f_output, "Content-Transfer-Encoding: base64\n");
+		}
+		removeCR(item->email->body);
+		if (base64_body)
+			write_email_body(f_output, base64_encode(item->email->body,
+								 strlen(item->email->body)));
+		else
+			write_email_body(f_output, item->email->body);
+	}
+	
+	if (item->email->htmlbody != NULL) {
+		if (boundary) {
+			fprintf(f_output, "\n--%s\n", boundary);
+			fprintf(f_output, "Content-type: text/html\n\n");
+			if (base64_body)
+				fprintf(f_output, "Content-Transfer-Encoding: base64\n");
+		}
+		removeCR(item->email->htmlbody);
+		if (base64_body)
+			write_email_body(f_output, base64_encode(item->email->htmlbody,
+								 strlen(item->email->htmlbody)));
+		else
+			write_email_body(f_output, item->email->htmlbody);
+	}
+
+	if (item->email->rtf_compressed != NULL) {
+		DEBUG_MAIN(("Adding RTF body as attachment\n"));
+		item->current_attach = (pst_item_attach*)xmalloc(sizeof(pst_item_attach));
+		memset(item->current_attach, 0, sizeof(pst_item_attach));
+		item->current_attach->next = item->attach;
+		item->attach = item->current_attach;
+		item->current_attach->data = lzfu_decompress(item->email->rtf_compressed);
+		item->current_attach->filename2 = xmalloc(strlen(RTF_ATTACH_NAME)+2);
+		strcpy(item->current_attach->filename2, RTF_ATTACH_NAME);
+		item->current_attach->mimetype = xmalloc(strlen(RTF_ATTACH_TYPE)+2);
+		strcpy(item->current_attach->mimetype, RTF_ATTACH_TYPE);
+		memcpy(&(item->current_attach->size), item->email->rtf_compressed+sizeof(int32_t), sizeof(int32_t));
+		LE32_CPU(item->current_attach->size);
+		//	  item->email->rtf_compressed = ;
+		//	  attach_num++;
+	}
+	if (item->email->encrypted_body || item->email->encrypted_htmlbody) {
+		// if either the body or htmlbody is encrypted, add them as attachments
+		if (item->email->encrypted_body) {
+			DEBUG_MAIN(("Adding Encrypted Body as attachment\n"));
+			item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
+			memset(item->current_attach, 0, sizeof(pst_item_attach));
+			item->current_attach->next = item->attach;
+			item->attach = item->current_attach;
+	    
+			item->current_attach->data = item->email->encrypted_body;
+			item->current_attach->size = item->email->encrypted_body_size;
+			item->email->encrypted_body = NULL;
+		}
+		if (item->email->encrypted_htmlbody) {
+			DEBUG_MAIN(("Adding encrypted HTML body as attachment\n"));
+			item->current_attach = (pst_item_attach*) xmalloc(sizeof(pst_item_attach));
+			memset(item->current_attach, 0, sizeof(pst_item_attach));
+			item->current_attach->next = item->attach;
+			item->attach = item->current_attach;
+
+			item->current_attach->data = item->email->encrypted_htmlbody;
+			item->current_attach->size = item->email->encrypted_htmlbody_size;
+			item->email->encrypted_htmlbody = NULL;
+		}
+		write_email_body(f_output, "The body of this email is encrypted. This isn't supported yet, but the body is now an attachment\n");
+	}
+	base64_body = 0;
+	// attachments
+	for(item->current_attach = item->attach;
+	    item->current_attach;
+	    item->current_attach = item->current_attach->next) {
+		DEBUG_MAIN(("main: Attempting Attachment encoding\n"));
+		if (item->current_attach->data == NULL) {
+			DEBUG_MAIN(("main: Data of attachment is NULL!. Size is supposed to be %i\n", item->current_attach->size));
+		}
+		if (mode == MODE_SEPERATE)
+			write_separate_attachment(f_name, item->current_attach, attach_num, pst);
+		else
+			write_inline_attachment(f_output, item->current_attach, boundary, pst);
+		attach_num++;
+	}
+	if (mode != MODE_SEPERATE) {
+		DEBUG_MAIN(("main: Writing buffer between emails\n"));
+		if (boundary)
+			fprintf(f_output, "\n--%s--\n", boundary);
+		fprintf(f_output, "\n\n");
+	}
+	// }}}2
+	if (boundary)
+		free (boundary);
+}



More information about the Libpst-devel mailing list