data_obj->buffer = (char *) PR_Malloc(POST_DATA_BUFFER_SIZE);
data_obj->buffer = (char *) PR_Calloc(1, POST_DATA_BUFFER_SIZE);
NET_WritePostData(MWContext  *context,				  URL_Struct *URL_s,				  PRFileDesc   *sock,				  void      **write_post_data_data,				  PRBool     add_crlf_to_line_endings){	struct WritePostDataData *data_obj = (struct WritePostDataData *) 														*write_post_data_data;	/* init the data object */	if(!data_obj)	  {		data_obj = PR_NEW(struct WritePostDataData);		*write_post_data_data = data_obj;		if(!data_obj)			return(MK_OUT_OF_MEMORY);		memset(data_obj, 0, sizeof(struct WritePostDataData));		data_obj->last_line_was_complete = TRUE;		data_obj->buffer = (char *) PR_Malloc(POST_DATA_BUFFER_SIZE);		if(!data_obj->buffer)		{			NET_free_write_post_data_object(data_obj);			*write_post_data_data=NULL;			return 0;		}		if(URL_s->post_headers)			data_obj->headerSize = PL_strlen(URL_s->post_headers);		else			data_obj->headerSize = 0;		data_obj->headerAmountSent = 0;		data_obj->CRSent = FALSE;		data_obj->LFSent = FALSE;		data_obj->amt_sent = 0;	  }    if(!data_obj->fp && URL_s->post_data_is_file)      {	  	XP_StatStruct stat_entry;		/* Send the headers */		if( URL_s->post_headers && 			(data_obj->headerSize > data_obj->headerAmountSent) )		{		    int32 amtWritten = 0;			amtWritten = PR_Write(sock, 					URL_s->post_headers + data_obj->headerAmountSent, 					data_obj->headerSize - data_obj->headerAmountSent);						/* if there was a problem */			if( amtWritten < 0 ) {				/* determine whether it was expected */				if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )					return 1;				else 					return(MK_TCP_WRITE_ERROR);			}#ifdef DEBUG			NET_NTrace("Tx: ", 4);			NET_NTrace(URL_s->post_headers + data_obj->headerAmountSent,                    		   amtWritten);#endif			data_obj->headerAmountSent += amtWritten;			if(data_obj->headerSize > data_obj->headerAmountSent)				return 1;		} /* END: URL_s->post_headers ... */		/* stat the file to get the size		 */		if(-1 != XP_Stat(URL_s->post_data, &stat_entry, xpFileToPost))		  {		  	data_obj->file_size = stat_entry.st_size;		  }		  	        /* open the post data file         */        data_obj->fp = XP_FileOpen(URL_s->post_data, xpFileToPost, XP_FILE_READ_BIN);        if(!data_obj->fp)          {            URL_s->error_msg = NET_ExplainErrorDetails(                                                    MK_UNABLE_TO_LOCATE_FILE,                                                    URL_s->post_data);			NET_free_write_post_data_object(data_obj);			*write_post_data_data = NULL;            return(MK_UNABLE_TO_LOCATE_FILE);          }      }    if(URL_s->post_data_is_file)      {        int32 amt_to_wrt;        int32 amt_wrt;		int type = NET_URL_Type (URL_s->address);		XP_Bool quote_lines_p = (type == MAILTO_TYPE_URL ||								 type == NEWS_TYPE_URL ||								 type == INTERNAL_NEWS_TYPE_URL);        /* do file based operations         */        if(data_obj->amt_in_buffer < 1 || data_obj->amt_sent >= data_obj->amt_in_buffer)          {            /* read more data from the file             */			if (quote_lines_p || add_crlf_to_line_endings)			  {				char *line;				char *b = data_obj->buffer;				int32 bsize = POST_DATA_BUFFER_SIZE;				data_obj->amt_in_buffer =  0;				do {				  int L;				  line = XP_FileReadLine(b, bsize-5, data_obj->fp);				  if (!line)					break;				  L = PL_strlen(line);				  /* escape periods only if quote_lines_p is set				   */				  if (quote_lines_p &&					  data_obj->last_line_was_complete && line[0] == '.')					{					  /* This line begins with "." so we need to quote it						 by adding another "." to the beginning of the line.					   */					  int i;					  line[L+1] = 0;					  for (i = L; i > 0; i--)						line[i] = line[i-1];					  L++;					}				  /* set default */				  data_obj->last_line_was_complete = TRUE;				  if (L > 1 && line[L-2] == CR && line[L-1] == LF)				 	{						/* already ok */					}				  else if(L > 0 && (line[L-1] == LF || line[L-1] == CR))					{					  /* only add the crlf if required					   * we still need to do all the					   * if comparisons here to know					   * if the line was complete					   */					  if(add_crlf_to_line_endings)					 	{					  	  /* Change newline to CRLF. */					  	  L--;					  	  line[L++] = CR;					  	  line[L++] = LF;					  	  line[L] = 0;						}					}				  else				    {					  data_obj->last_line_was_complete = FALSE;					}				  bsize -= L;				  b += L;				  data_obj->amt_in_buffer += L;				} while (line && bsize > 100);			  }			else			  {				data_obj->amt_in_buffer = XP_FileRead(data_obj->buffer,											   POST_DATA_BUFFER_SIZE-1,											   data_obj->fp);			  }HG29784			            if(data_obj->amt_in_buffer < 1)              {                /* end of file, all done                 */				/* 				 * handled by NET_free_write_post_data_object 				 *				XP_FileClose(data_obj->fp);				*/				PR_ASSERT(data_obj->total_amt_sent >= data_obj->file_size);				NET_free_write_post_data_object(data_obj);				*write_post_data_data = NULL;                return(0);              }            data_obj->amt_sent = 0;          }        amt_to_wrt = data_obj->amt_in_buffer-data_obj->amt_sent;        /* write some data to the socket         */        amt_wrt = PR_Write(sock,                           data_obj->buffer+data_obj->amt_sent,                           amt_to_wrt);#ifdef DEBUG		NET_NTrace("Tx: ", 4);		NET_NTrace(data_obj->buffer+data_obj->amt_sent,                   amt_to_wrt);#endif /* DEBUG */        if(amt_wrt < 0) 		  {            int err = PR_GetError();            if(err == PR_WOULD_BLOCK_ERROR 				|| err == PR_IS_CONNECTED_ERROR)                return(1); /* continue */            URL_s->error_msg = NET_ExplainErrorDetails(MK_TCP_WRITE_ERROR, err);			/*			 * handled by net_free_write_post_data			XP_FileClose(data_obj->fp);			*/			NET_free_write_post_data_object(data_obj);			*write_post_data_data = NULL;            return(MK_TCP_WRITE_ERROR);          }#if defined(XP_UNIX) && defined(DEBUG)        if(amt_wrt < amt_to_wrt)           fprintf(stderr, "Fwrite wrote less than requested!\n");#endif        /* safety for broken write */        if(amt_wrt > amt_to_wrt)            amt_wrt = amt_to_wrt;#if defined(XP_UNIX) && defined(DEBUG)    if(MKLib_trace_flag)      {        fwrite("Tx: ", 1, 4, stderr);		fwrite(data_obj->buffer+data_obj->amt_sent, 1, amt_wrt, stderr);        fwrite("\n", 1, 1, stderr);      }#endif        data_obj->amt_sent += amt_wrt;		data_obj->total_amt_sent += amt_wrt;		/* return the amount of data written		 * so that callers can provide progress		 * if necessary.  If the amt_wrt was		 * zero (I don't think it can ever happen)		 * return 1 because zero means all done		 */		if(amt_wrt > 0)			return(amt_wrt);		else			return(1);      }    else      {		/* do memory based operations */		int32 amtWritten;	    /* send the headers if there are any && and they haven't been sent */        if( URL_s->post_headers && (data_obj->headerSize > data_obj->headerAmountSent) )          {			amtWritten = PR_Write(sock, 					URL_s->post_headers + data_obj->headerAmountSent, 					data_obj->headerSize - data_obj->headerAmountSent);			/* if there was a problem */			if(amtWritten < 0) {				/* determine whether it was expected */				if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )					return 1;				else 					return(MK_TCP_WRITE_ERROR);			}#ifdef DEBUG			NET_NTrace("Tx: ", 4);			NET_NTrace(URL_s->post_headers + data_obj->headerAmountSent,                    		   amtWritten);			NET_NTrace("\n", 1);#endif			data_obj->headerAmountSent += amtWritten;			/* If all the header data hasn't been sent, return 1 (not done). */			if(data_obj->headerSize > data_obj->headerAmountSent)				return 1;          }		/* Separate the headers from the data with a CR and LF. */#if defined(MODULAR_NETLIB)		if(URL_s->post_headers && !data_obj->CRSent) {#else		if(!data_obj->CRSent) {#endif			data_obj->buffer[0] = CR;			data_obj->buffer[1] = LF;			data_obj->buffer[2] = '\0';			amtWritten = PR_Write(sock, data_obj->buffer, PL_strlen(data_obj->buffer));			if(amtWritten < 0) {				/* determine whether it was expected */				if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )					return 1;				else 					return(MK_TCP_WRITE_ERROR);			  }			/* If no data was sent, return 1 (not done). */			if(amtWritten == 0)				return 1;			if(amtWritten >= 1)				data_obj->CRSent = TRUE;			if(amtWritten >= 2)				data_obj->LFSent = TRUE;		}#if defined(MODULAR_NETLIB)		if(URL_s->post_headers && !data_obj->LFSent) {#else		if(!data_obj->LFSent) {#endif			data_obj->buffer[0] = LF;			data_obj->buffer[1] = '\0';			amtWritten = PR_Write(sock, data_obj->buffer, PL_strlen(data_obj->buffer));			if(amtWritten < 0) {				/* determine whether it was expected */				if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )					return 1;				else 					return(MK_TCP_WRITE_ERROR);			  }			/* If no data was sent, return 1 (not done). */			if(amtWritten == 0)				return 1;			data_obj->LFSent = TRUE;			TRACEMSG(("Adding \\n to command"));		}        if(!URL_s->post_data)		  {			NET_free_write_post_data_object(data_obj);			*write_post_data_data = NULL;            return(MK_OUT_OF_MEMORY);		  }		/* Send the data if we haven't already sent it */		if(URL_s->post_data_size > data_obj->amt_sent) {			amtWritten = PR_Write(sock,								URL_s->post_data+data_obj->amt_sent,								URL_s->post_data_size-data_obj->amt_sent);			if(amtWritten < 0) {				/* determine whether it was expected */				if( net_expected_error(URL_s, (struct WritePostDataData **) write_post_data_data) )					return 1;				else 					return(MK_TCP_WRITE_ERROR);			  }			/* If no data was sent, return 1 (not done). */				if(amtWritten == 0)				return 1;#ifdef DEBUG			NET_NTrace("Tx: ", 4);			NET_NTrace(URL_s->post_data+data_obj->amt_sent,                   	   amtWritten);			NET_NTrace("\n", 1);#endif			data_obj->amt_sent += amtWritten;			/* if all data has been written, return done */			if(data_obj->amt_sent >= URL_s->post_data_size)	{				NET_free_write_post_data_object(data_obj);				*write_post_data_data = NULL;				return 0;			}			else {				return amtWritten;			}		}		else {			NET_free_write_post_data_object(data_obj);			*write_post_data_data = NULL;			return 0;		}      }	/* By this time all headers and data should have been sent, shouldn't get here */	PR_ASSERT(0);	NET_free_write_post_data_object(data_obj);	*write_post_data_data = NULL;	return(-1); /* shouldn't ever get here */}