zOPER_EXPORT void OPERATION MakeShortString( CDC *pDC, zPCHAR pchReturn, zLONG lMaxReturnLth, zCPCHAR cpcString, zLONG lColLth, zLONG lOffset ) { static const _TCHAR szThreeDots[ ] = _T( "..." ); if ( lMaxReturnLth == 0 ) { pchReturn[ 0 ] = 0; return; } zstrncpy( pchReturn, cpcString, lMaxReturnLth ); pchReturn[ lMaxReturnLth ] = 0; zSHORT nStringLth = zstrlen( cpcString ); CSize size; zSHORT k; zCHAR szFontFace[ 32 ]; GetTextFace( pDC->m_hDC, sizeof( szFontFace ), szFontFace ); GetTextFace( pDC->m_hAttribDC, sizeof( szFontFace ), szFontFace ); GetTextExtentPoint32( pDC->m_hDC, cpcString, nStringLth, &size ); if ( pDC->m_bPrinting ) GetTextExtentPoint32( pDC->m_hAttribDC, cpcString, nStringLth, &size ); if ( nStringLth == 0 || (size.cx + lOffset) <= lColLth ) return; GetTextExtentPoint32( pDC->m_hDC, szThreeDots, sizeof( szThreeDots ), &size ); zLONG lAddLth = size.cx; for ( k = nStringLth - 1; k > 0; k-- ) { pchReturn[ k ] = 0; GetTextExtentPoint32( pDC->m_hDC, pchReturn, k, &size ); if ( pDC->m_bPrinting ) GetTextExtentPoint32( pDC->m_hAttribDC, pchReturn, k, &size ); if ( (size.cx + lOffset + lAddLth) <= lColLth ) break; } zstrcat( pchReturn, szThreeDots ); }
/*------------------------------------------------------------------------ Procedure: MIMEH_parse_filename ID:1 Purpose: Reads in a given filename, and cleans it up, removes any risky components Input: Output: Errors: ------------------------------------------------------------------------*/ int MIMEH_parse_filename( char *dest, char *raw ) { char c = '\0'; char *p, *q, *n; int qp_encode = 0; int quoted = 0; char tmp[_MIMEH_STRLEN_MAX+1]; n = strpbrk(raw,"\n\r;"); if (n) { c = *n; *n = '\0'; } zstrncpy(tmp,raw,_MIMEH_STRLEN_MAX); p = tmp; if (XAM_strncasecmp(p,"\"3d",3)==0) { qp_encode = 1; quoted=1; p+=3; } else if (XAM_strncasecmp(p,"3d\"",3)==0) { qp_encode = 1; quoted = 1; p+=3; } else if (XAM_strncasecmp(p,"3d",2)==0) { qp_encode = 1; quoted=0; p+=2; } else if ((*p) == '\"') { qp_encode = 0; quoted = 1; p++; } if ((qp_encode)&&(strstr(p,"=OA="))) qp_encode = 1; else qp_encode = 0; snprintf(dest,_MIMEH_FILENAMELEN_MAX,"%s",p); if (qp_encode) MIMEH_decode_qp(dest); if (quoted) { q = strrchr(dest,'\"'); if (q) *q = '\0'; } if (n) *n = c; return 0; }
/*------------------------------------------------------------------------ Procedure: MIMEH_parse_headers ID:1 Purpose: Reads an open filestream in and parses the headers for it. Input: Output: Errors: ------------------------------------------------------------------------*/ int MIMEH_parse_headers( FFGET_FILE *f, struct _header_info *hinfo ) { char *safeh, *h, *hl, *safehl; char *p,*q, c, *pre_p; char *lba; char *line_end; char *next_angle; int result; int headerlength; if (MIMEH_DNORMAL) fprintf(stdout,"MIMEH_parse_headers: Start [F=%p, hinfo=%p]\n", f, hinfo); MIMEH_init_hexconv(); FFGET_set_watch_SDL(1); result = MIMEH_read_headers(f); FFGET_set_watch_SDL(0); hinfo->filename[0] = '\0'; hinfo->name[0] = '\0'; safeh = h = MIMEH_headerline; // If we ran out of input whilst looking at headers, then, we basically // flag this, free up the headers, and return. if (result == -1) { if (MIMEH_headerline) free(MIMEH_headerline); return result; } if (!MIMEH_headerline) { if (MIMEH_DNORMAL) fprintf(stderr,"DEBUG:%s:%d: null MIMEH_headerline\n",__FILE__,__LINE__); return 1; } // Duplicate string headerlength = strlen(h); safehl = hl = malloc(sizeof(char) *(headerlength+1)); zstrncpy(hl,h, headerlength+1); strlower(hl); if (MIMEH_DNORMAL) fprintf(stdout,"DEBUG:%s:%d: Header length = %d\n",__FILE__,__LINE__,headerlength); // CONTENT TYPE ------------------------------- // CONTENT TYPE ------------------------------- // CONTENT TYPE ------------------------------- hinfo->content_type = _CTYPE_UNKNOWN; p = strstr(hl,"content-type"); if (p) { p = p +strlen("content-type"); q = strpbrk(p,"\n\r;"); if (q) { c = *q; *q = '\0'; if (strstr(p,"multipart/")) hinfo->content_type = _CTYPE_MULTIPART; else if (strstr(p,"text/")) hinfo->content_type = _CTYPE_TEXT; else if (strstr(p,"message/rfc822")) hinfo->content_type = _CTYPE_RFC822; else if (strstr(p,"/octet-stream")) hinfo->content_type = _CTYPE_OCTECT; else if (strstr(p,"/ms-tnef")) hinfo->content_type = _CTYPE_TNEF; else hinfo->content_type = _CTYPE_UNKNOWN; *q = c; } else { syslog(1,"MIMEH_parse_headers(): Cannot locate end of Content-Type specifier!"); } } // CONTENT LOCATION ------------------------------- // CONTENT LOCATION ------------------------------- // CONTENT LOCATION ------------------------------- p = strstr(hl,"content-location:"); if (p) { if (MIMEH_DNORMAL) fprintf(stdout,"%s:%d: Content Location line found - '%s'\n",__FILE__,__LINE__,p); q = strrchr(p,'/'); if (!q) q = strrchr(p,':'); if (q) { p = h +(q -hl); MIMEH_parse_filename(hinfo->filename, p); snprintf(hinfo->name,sizeof(hinfo->name),"%s",hinfo->filename); } else hinfo->filename[0] = '\0'; } // ATTACHMENT FILENAME ---------------------------- // ATTACHMENT FILENAME ---------------------------- // ATTACHMENT FILENAME ---------------------------- p = strstr(hl,"filename="); if (p) { if (MIMEH_DNORMAL) fprintf(stdout,"MIME_headers: %d: %s",__LINE__,hl); p = p +strlen("filename="); p = h +(p -hl); MIMEH_parse_filename(hinfo->filename, p); snprintf(hinfo->name,sizeof(hinfo->name),"%s",hinfo->filename); } else hinfo->filename[0] = '\0'; // ATTACHMENT -NAME ---------------------------- // ATTACHMENT -NAME ---------------------------- // ATTACHMENT -NAME ---------------------------- if (hinfo->filename[0] == '\0') { p = strstr(hl,"name="); if ( (p) && (isspace(*(p-1))) ) { // Because HTML in MIME is so common these days, it's not // unusual to get a <META .... name="..."> tag in the headers // hence, it's a good idea to text for the trailing > (which // is not a legal filechar anyhow!) and REJECT if it contains // it next_angle = line_end = NULL; next_angle=strchr(p,'>'); if (next_angle) line_end=strpbrk(p,"\n\r\";"); if ( (!next_angle) || (line_end && (line_end < next_angle)) ) { p = p +strlen("name="); p = h +(p -hl); MIMEH_parse_filename(hinfo->name, p); } } } // If we got a filename in one, but not the other hinfo-> seach, then // Duplicate if ((hinfo->filename[0] == '\0')&&(hinfo->name[0] != '\0')) { snprintf(hinfo->filename,_MIMEH_FILENAMELEN_MAX,"%s",hinfo->name); } // CONTENT TRANSFER ENCODING --------------------- // CONTENT TRANSFER ENCODING --------------------- // CONTENT TRANSFER ENCODING --------------------- p = strstr(hl,"content-transfer-encoding"); if (p) { p = p +strlen("content-transfer-encoding"); q = strpbrk(p,"\n\r;"); if (q) { c = *q; *q = '\0'; if (strstr(p,"base64")) { hinfo->content_transfer_encoding = _CTRANS_ENCODING_B64; } else if (strstr(p,"7bit")) { hinfo->content_transfer_encoding = _CTRANS_ENCODING_7BIT; } else if (strstr(p,"8bit")) { hinfo->content_transfer_encoding = _CTRANS_ENCODING_8BIT; } else if (strstr(p,"quoted-printable")) { hinfo->content_transfer_encoding = _CTRANS_ENCODING_QP; } else if (strstr(p,"uuencode")) { hinfo->content_transfer_encoding = _CTRANS_ENCODING_UUENCODE; } else hinfo->content_transfer_encoding = _CTRANS_ENCODING_RAW; *q = c; } else { syslog(1,"MIMEH_parse_headers(): Cannot locate end of Content-Transfer-Encoding specifier!"); } } else hinfo->content_transfer_encoding = _CTRANS_ENCODING_RAW; // CONTENT DISPOSITION ------------------------------ // CONTENT DISPOSITION ------------------------------ // CONTENT DISPOSITION ------------------------------ p = strstr(hl,"content-disposition"); if (p) { p = p +strlen("content-disposition"); q = strpbrk(p,"\n\r;"); if (q) { c = *q; *q = '\0'; if (strstr(p,"inline")) hinfo->content_disposition = _CDISPOSITION_INLINE; else if (strstr(p,"form-data")) { hinfo->content_disposition = _CDISPOSITION_FORMDATA; hinfo->content_type = _CDISPOSITION_FORMDATA; } else if (strstr(p,"attachment")) hinfo->content_disposition = _CDISPOSITION_ATTACHMENT; else hinfo->content_disposition = _CDISPOSITION_UNKNOWN; *q = c; } else { syslog(1,"MIMEH_parse_headers(): Cannot locate end of Content-Disposition specifier!"); } } // Seeking out boundaries is not quite as simple as it seems. // we can "initially" think that we can just do a "strstr", but // what if there is a filename="someboundary=OAxxx.gif" then // we're in trouble! // lba = hl; p = strstr(lba, "boundary="); while ( (lba != NULL) && (hinfo->boundary_located==0) && ( p != NULL) ) { if (MIMEH_DNORMAL) fprintf(stdout,"DEBUG:MIME_headers:%s:%d:Looking for headers...(%s)\n",__FILE__,__LINE__,(p-2)); if (p == NULL) break; // Setup a pointer to the char just before this boundary= location if (p > hl) { pre_p = p -1; } else pre_p = NULL; // If the previous char from 'p' is not a ; or "space", then it's not possible for this // to be a BOUNDARY if ( (pre_p) && (!isspace(*pre_p)) && (*pre_p != ';') ) { if (MIMEH_DNORMAL) fprintf(stdout,"DEBUG:%s:%d:Previous char '%c' is NOT blank, move along now...\n",__FILE__,__LINE__, *pre_p); p = strstr(p +strlen("boundary="),"boundary="); continue; } // fprintf(stdout,"Testing boundary at: %s",p); p = p +strlen("boundary="); p = h +(p -hl); // If we have a quoted boundary, shift one char to the right if ((*p) == '\"') p++; // Try to find the end of the boundary by looking for ", \n, \r \t or ; q = strpbrk(p,"\"\n\r\t;"); // If we did find something for the end of the boundary if (q) { // If the first char of the boundary isn't a normal alphanumeric char if (!(isprint(*p))) { // Move our start point (for detecting boundaries in the headers) // alone one more char... lba++; // Try find a new boundary... p = strstr(lba,"boundary="); continue; } else { // if the character was valid, then we have detected a boundary // specifier!. Copy this to the hinfo structure, and set the // "located" flag // get the character which we stopped on c = *q; // turn the location into a string terminator *q = '\0'; snprintf(hinfo->boundary,_MIMEH_STRLEN_MAX,"%s",p); hinfo->boundary_located = 1; *q = c; } // Set our string terminator location back to its original character // (if we dont, then any further string operations wont see beyond // it) } else { syslog(1,"MIMEH_parse_headers(): Cannot locate end of boundary specifier!"); } } // while if (safehl) free(safehl); else fprintf(stderr,"%s:%d:WARNING - Unable to free HEADERS allocated memory\n",__FILE__,__LINE__);// if (hlorg) free(hlorg); if (safeh) { free(safeh); MIMEH_headerline = NULL; } else fprintf(stdout,"%s:%d:WARNING - Unable to free HEADERS allocated memory\n",__FILE__,__LINE__); if (MIMEH_DNORMAL) fprintf(stdout,"MIMEH_parse_headers: END [F=%p, hinfo=%p]\n", f, hinfo); return 0; }
/*------------------------------------------------------------------------ Procedure: MIMEH_read_headers ID:1 Purpose: Reads from the stream F until it detects a From line, or a blank line (end of headers) Input: Output: Errors: ------------------------------------------------------------------------*/ int MIMEH_read_headers( FFGET_FILE *f ) { char line[_MIMEH_STRLEN_MAX+1]; int totalsize=0; int linesize=0; int result = 0; int firstline = 1; int hl; char *tmp; char *fget_result = NULL; char *headerline_end; MIMEH_headerline = NULL; if (MIMEH_DNORMAL) fprintf(stdout,"DEBUG: MIME_headers: Starting read\n"); while ((fget_result=FFGET_fgets(line,_MIMEH_STRLEN_MAX, f))) { if (MIMEH_DNORMAL) fprintf(stdout,"DEBUG: MIME_headers: [blank = %d] Read: \n%s",f->trueblank,line); linesize = strlen(line); totalsize += linesize; tmp = realloc(MIMEH_headerline, totalsize+1); if (!tmp) { syslog(1,"MIMEH_read_headers(): cannot allocate %d bytes ",totalsize); free(MIMEH_headerline); MIMEH_headerline = NULL; return -1; } if (!MIMEH_headerline) { MIMEH_headerline = tmp; zstrncpy(MIMEH_headerline, line, (linesize +1)); headerline_end = MIMEH_headerline +totalsize; } else { hl = totalsize -linesize; MIMEH_headerline = tmp; memcpy((MIMEH_headerline +hl), line, (linesize+1)); // strcat(MIMEH_headerline,line); } if (f->trueblank) { if (MIMEH_DNORMAL) fprintf(stdout,"DEBUG: MIME_headers: True BLANK LINE located, terminating header read\n"); if ((MIMEH_save_headers)&&(MIMEH_headerline)) { fprintf(MIMEH_fh,"%s",MIMEH_headerline); } if (MIMEH_DNORMAL) fprintf(stdout,"%s:%d------------------headers:\n%s\n(TRUE-END Found)\n",__FILE__,__LINE__,MIMEH_headerline); result = 1; break; } // If there was a doubleCR at the end of the line, // then we need to save the next set of data until there // is a \n if (FFGET_doubleCR) { MIMEH_save_doubleCR(f); FFGET_doubleCR = 0; MIMEH_doubleCR = 1; FFGET_SDL_MODE = 0; } firstline = 0; } // If FFGET ran out of data whilst processing the headers, then acknowledge this // by returning a -1. // // NOTE - This does not mean we do not have any data! // it just means that our input ran out. if (!fget_result) { result = -1; } // fprintf(stderr,"DEBUG:Exiting MIME_read_headers()\n"); return result; }