misc.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:20k
- /***************************************
- $Header: /home/amb/wwwoffle/RCS/misc.c 2.40 2000/02/20 09:44:01 amb Exp $
- WWWOFFLE - World Wide Web Offline Explorer - Version 2.5d.
- Miscellaneous HTTP / HTML functions.
- ******************/ /******************
- Written by Andrew M. Bishop
- This file Copyright 1997,98,99,2000 Andrew M. Bishop
- It may be distributed under the GNU Public License, version 2, or
- any higher version. See section COPYING of the GNU Public license
- for conditions under which this file may be redistributed.
- ***************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <time.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <errno.h>
- #include "misc.h"
- #include "errors.h"
- #include "proto.h"
- #include "config.h"
- #include "md5.h"
- /*++++++++++++++++++++++++++++++++++++++
- Split a URL into a protocol, hostname, path name and an argument list.
- URL *SplitURL Returns a URL structure containing the information.
- char *url The name of the url to split.
- ++++++++++++++++++++++++++++++++++++++*/
- URL *SplitURL(char *url)
- {
- URL *Url=(URL*)malloc(sizeof(URL));
- char *copyurl,*mallocurl=malloc(strlen(url)+2);
- int i=0,n=0;
- char *colon,*slash,*at,*ques,*temppath,root[2];
- copyurl=mallocurl;
- strcpy(copyurl,url);
- /* Protocol */
- colon=strchr(copyurl,':');
- slash=strchr(copyurl,'/');
- at =strchr(copyurl,'@');
- if(slash==copyurl) /* /dir/... (local) */
- {
- Url->proto=(char*)malloc(5);
- strcpy(Url->proto,"http");
- }
- else if(colon && slash && (colon+1)==slash) /* http://... */
- {
- *colon=0;
- Url->proto=(char*)malloc(colon-copyurl+1);
- strcpy(Url->proto,copyurl);
- copyurl=slash+1;
- if(*copyurl=='/')
- copyurl++;
- colon=strchr(copyurl,':');
- slash=strchr(copyurl,'/');
- }
- else if(colon && !isdigit(*(colon+1)) &&
- (!slash || colon<slash) &&
- (!at || (slash && at>slash))) /* http:www.foo.com/...[:@]... */
- {
- *colon=0;
- Url->proto=(char*)malloc(colon-copyurl+1);
- strcpy(Url->proto,copyurl);
- copyurl=colon+1;
- colon=strchr(copyurl,':');
- }
- else /* www.foo.com:80/... */
- {
- Url->proto=(char*)malloc(5);
- strcpy(Url->proto,"http");
- }
- for(i=0;Url->proto[i];i++)
- Url->proto[i]=tolower(Url->proto[i]);
- Url->Protocol=NULL;
- for(i=0;i<NProtocols;i++)
- if(!strcmp(Protocols[i].name,Url->proto))
- Url->Protocol=&Protocols[i];
- /* Password */
- if(at && at>copyurl && (!slash || slash>at))
- {
- if(colon && at>colon) /* user:pass@www.foo.com...[/]... */
- {
- *colon=0;
- Url->user=URLDecode(copyurl,0);
- copyurl=colon+1;
- *at=0;
- Url->pass=URLDecode(copyurl,0);
- copyurl=at+1;
- }
- else /* user@www.foo.com...[:/]... */
- {
- *at=0;
- Url->user=URLDecode(copyurl,0);
- copyurl=at+1;
- Url->pass=NULL;
- }
- }
- else
- {
- if(at==copyurl) /* @www.foo.com... */
- copyurl++;
- Url->user=NULL;
- Url->pass=NULL;
- }
- /* Arguments */
- ques=strchr(copyurl,'?');
- if(ques) /* ../path?... */
- {
- *ques++=0;
- Url->args=(char*)malloc(strlen(ques)+1);
- strcpy(Url->args,ques);
- }
- else
- Url->args=NULL;
- /* Hostname */
- if(*copyurl=='/') /* /path/... (local) */
- {
- Url->host=GetLocalHost(1);
- Url->local=1;
- }
- else /* www.foo.com... */
- {
- Url->host=copyurl;
- Url->local=0;
- if(slash && (!ques || slash<ques)) /* www.foo.com/...[?]... */
- copyurl=slash;
- else /* www.foo.com[?]... */
- {root[0]='/';root[1]=0;copyurl=root;}
- }
- /* Pathname */
- temppath=URLDecode(copyurl,0);
- Url->path=URLEncode(temppath);
- free(temppath);
- /* Hostname (cont) */
- if(!Url->local)
- {
- *copyurl=0;
- copyurl=Url->host;
- Url->host=(char*)malloc(strlen(copyurl)+1);
- strcpy(Url->host,copyurl);
- }
- for(i=0;Url->host[i] && Url->host[i]!=':';i++)
- Url->host[i]=tolower(Url->host[i]);
- if(Url->host[i]==':')
- if(atoi(&Url->host[i+1])==(Url->Protocol?Url->Protocol->defport:80))
- Url->host[i]=0;
- if(!Url->local && IsLocalHost(Url->host,1) && Url->Protocol && Url->Protocol==&Protocols[0])
- {
- free(Url->host);
- Url->host=GetLocalHost(1);
- Url->local=1;
- }
- /* Canonicalise the URL. */
- Url->name=(char*)malloc(strlen(Url->proto)+strlen(Url->host)+strlen(Url->path)+(Url->args?strlen(Url->args):1)+8);
- strcpy(Url->name,Url->proto);
- n=strlen(Url->proto);
- strcpy(Url->name+n,"://");
- n+=3;
- Url->hostp=Url->name+n;
- strcpy(Url->name+n,Url->host);
- n+=strlen(Url->host);
- Url->pathp=Url->name+n;
- strcpy(Url->name+n,Url->path);
- n+=strlen(Url->path);
- if(Url->args && *Url->args)
- {
- strcpy(Url->name+n,"?");
- strcpy(Url->name+n+1,Url->args);
- }
- if(Url->user)
- {
- Url->file=(char*)malloc(strlen(Url->proto)+strlen(Url->hostp)+strlen(Url->user)+(Url->pass?strlen(Url->pass):0)+8);
- n=Url->hostp-Url->name;
- strncpy(Url->file,Url->name,n);
- strcpy(Url->file+n,Url->user);
- n+=strlen(Url->user);
- if(Url->pass)
- {
- strcpy(Url->file+n,":");
- strcpy(Url->file+n+1,Url->pass);
- n+=strlen(Url->pass)+1;
- }
- strcpy(Url->file+n,"@");
- strcpy(Url->file+n+1,Url->hostp);
- }
- else
- Url->file=Url->name;
- if(Url->Protocol && !Url->Protocol->proxyable)
- {
- char *localhost=GetLocalHost(1);
- Url->link=(char*)malloc(strlen(Url->name)+strlen(localhost)+8);
- sprintf(Url->link,"http://%s/%s/%s",localhost,Url->proto,Url->hostp);
- }
- else
- Url->link=Url->name;
- Url->dir=Url->host;
- #if defined(__CYGWIN__)
- if(strchr(Url->host,':'))
- {
- char *colon=strchr(Url->host,':');
- Url->dir=(char*)malloc(strlen(Url->host));
- strcpy(Url->dir,Url->host);
- Url->dir[colon-Url->host]='!';
- }
- #endif
- /* end */
- free(mallocurl);
- return(Url);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Add a password to an existing URL.
- URL *Url The URL to add the username and password to.
- char *user The username.
- char *pass The password.
- ++++++++++++++++++++++++++++++++++++++*/
- void AddURLPassword(URL *Url,char *user,char *pass)
- {
- int n;
- Url->user=(char*)malloc(strlen(user)+1);
- strcpy(Url->user,user);
- if(pass)
- {
- Url->pass=(char*)malloc(strlen(pass)+1);
- strcpy(Url->pass,pass);
- }
- Url->file=(char*)malloc(strlen(Url->name)+strlen(Url->user)+(Url->pass?strlen(Url->pass):0)+8);
- n=Url->hostp-Url->name;
- strncpy(Url->file,Url->name,n);
- strcpy(Url->file+n,Url->user);
- n+=strlen(Url->user);
- if(Url->pass)
- {
- strcpy(Url->file+n,":");
- strcpy(Url->file+n+1,Url->pass);
- n+=strlen(Url->pass)+1;
- }
- strcpy(Url->file+n,"@");
- strcpy(Url->file+n+1,Url->hostp);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Free the memory in a URL.
- URL *Url The URL to free.
- ++++++++++++++++++++++++++++++++++++++*/
- void FreeURL(URL *Url)
- {
- if(Url->name!=Url->link)
- free(Url->link);
- if(Url->name!=Url->file)
- free(Url->file);
- if(Url->dir!=Url->host)
- free(Url->dir);
- free(Url->name);
- if(Url->proto) free(Url->proto);
- if(Url->host) free(Url->host);
- if(Url->path) free(Url->path);
- if(Url->args) free(Url->args);
- if(Url->user) free(Url->user);
- if(Url->pass) free(Url->pass);
- free(Url);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Convert a url reference from a page to an absolute one.
- char *LinkURL Return the linked to URL or the original link if unchanged.
- URL *Url The page that we are looking at.
- char *link The link from the page.
- ++++++++++++++++++++++++++++++++++++++*/
- char *LinkURL(URL *Url,char *link)
- {
- char *new=link;
- char *colon=strchr(link,':');
- char *slash=strchr(link,'/');
- if(colon && slash && colon<slash)
- ;
- else if(!*link)
- {
- new=(char*)malloc(strlen(Url->name));
- strcpy(link,Url->name);
- }
- else
- {
- if(*link=='/')
- {
- new=(char*)malloc(strlen(Url->proto)+strlen(Url->host)+strlen(link)+8);
- sprintf(new,"%s://%s%s",Url->proto,Url->host,link);
- }
- else
- {
- int j;
- char *path=(char*)malloc(strlen(Url->path)+strlen(link)+2);
- strcpy(path,Url->path);
- for(j=strlen(path);j>0;j--)
- if(path[j]=='/')
- break;
- path[j]=0;
- strcat(path,"/");
- strcat(path,link);
- CanonicaliseName(path);
- new=(char*)malloc(strlen(Url->proto)+strlen(Url->host)+strlen(path)+8);
- sprintf(new,"%s://%s%s",Url->proto,Url->host,path);
- free(path);
- }
- }
- return(new);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Canonicalise a file name by removing '/../', '/./' and '//' references.
- char *CanonicaliseName Returns the argument modified.
- char *name The original name
- ++++++++++++++++++++++++++++++++++++++*/
- char *CanonicaliseName(char *name)
- {
- char *match,*name2;
- match=name;
- while((match=strstr(match,"/./")) || !strncmp(match=name,"./",2))
- {
- char *prev=match, *next=match+2;
- while((*prev++=*next++));
- }
- match=name;
- while((match=strstr(match,"//")))
- {
- char *prev=match, *next=match+1;
- while((*prev++=*next++));
- }
- match=name2=name;
- while((match=strstr(match,"/../")))
- {
- char *prev=match, *next=match+4;
- if((prev-name2)==2 && !strncmp(name2,"../",3))
- {name2+=3;match++;continue;}
- while(prev>name2 && *--prev!='/');
- match=prev;
- if(*prev=='/')prev++;
- while((*prev++=*next++));
- }
- match=&name[strlen(name)-2];
- if(match>=name && !strcmp(match,"/."))
- *match=0;
- match=&name[strlen(name)-3];
- if(match>=name && !strcmp(match,"/.."))
- if(match==name)
- *++match=0;
- else
- while(match>name && *--match!='/')
- *match=0;
- #if 0 /* as used in cxref */
- match=&name[strlen(name)-1];
- if(match>name && !strcmp(match,"/"))
- *match=0;
- if(!*name)
- *name='.',*(name+1)=0;
- #else /* as used in wwwoffle */
- if(!*name || !strncmp(name,"../",3))
- *name='/',*(name+1)=0;
- #endif
- return(name);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Decode a string that has been UrlEncoded.
- char *URLDecode Returns a malloced copy of the decoded string.
- const char *str The string to be decoded.
- int isform Set to true if the string being decoded is from a form.
- ++++++++++++++++++++++++++++++++++++++*/
- char *URLDecode(const char *str, int isform)
- {
- int i,j;
- char *copy=(char*)malloc(strlen(str)+1);
- for(i=0,j=0;str[i];i++)
- if(str[i]=='+' && isform)
- copy[j++]=' ';
- else if(str[i]=='%')
- {
- unsigned int val=0;
- i++;
- if(str[i]>='a') val=str[i]-'a'+10;
- else if(str[i]>='A') val=str[i]-'A'+10;
- else val=str[i]-'0';
- val*=16;
- i++;
- if(str[i]>='a') val+=str[i]-'a'+10;
- else if(str[i]>='A') val+=str[i]-'A'+10;
- else val+=str[i]-'0';
- copy[j++]=val;
- }
- else
- copy[j++]=str[i];
- copy[j]=0;
- return(copy);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Decode a URL argument string that has been UrlEncoded.
- char *URLDecodeArgs Returns a malloced copy of the decoded string.
- const char *str The string to be decoded.
- ++++++++++++++++++++++++++++++++++++++*/
- char *URLDecodeArgs(const char *str)
- {
- int i,j;
- char *copy=(char*)malloc(strlen(str)+1);
- for(i=0,j=0;str[i];i++)
- if(str[i]=='%')
- {
- unsigned int val=0;
- i++;
- if(str[i]>='a') val=str[i]-'a'+10;
- else if(str[i]>='A') val=str[i]-'A'+10;
- else val=str[i]-'0';
- val*=16;
- i++;
- if(str[i]>='a') val+=str[i]-'a'+10;
- else if(str[i]>='A') val+=str[i]-'A'+10;
- else val+=str[i]-'0';
- if(val=='&' || val=='=')
- copy[j++]=str[i];
- else
- copy[j++]=val;
- }
- else
- copy[j++]=str[i];
- copy[j]=0;
- return(copy);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Encode a string using the UrlEncode method as used with the POST method.
- char *URLEncode Returns a malloced copy of the encoded string.
- const char *str The string to be encoded.
- ++++++++++++++++++++++++++++++++++++++*/
- char *URLEncode(const char *str)
- {
- int i,j;
- char *copy=(char*)malloc(3*strlen(str)+1);
- for(i=0,j=0;str[i];i++)
- if(isalpha(str[i]) ||
- isdigit(str[i]) ||
- str[i]=='/' || str[i]=='?' || str[i]=='@' || str[i]=='=' ||
- str[i]=='$' || str[i]=='-' || str[i]=='_' || str[i]=='.' || str[i]=='+' || str[i]=='!' ||
- str[i]=='*' || str[i]=='(' || str[i]==')' || str[i]==',' || str[i]==''')
- copy[j++]=str[i];
- else
- {
- unsigned int val=str[i];
- copy[j]='%';
- if(val%16>9)
- copy[j+2]=val%16+'A'-10;
- else
- copy[j+2]=val%16+'0';
- val/=16;
- if(val%16>9)
- copy[j+1]=val%16+'A'-10;
- else
- copy[j+1]=val%16+'0';
- j+=3;
- }
- copy[j]=0;
- return(copy);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Encode a string using the UrlEncode method as used for passwords in URLs.
- char *URLEncodePassword Returns a malloced copy of the encoded string.
- const char *str The string to be encoded.
- ++++++++++++++++++++++++++++++++++++++*/
- char *URLEncodePassword(const char *str)
- {
- int i,j;
- char *copy=(char*)malloc(3*strlen(str)+1);
- for(i=0,j=0;str[i];i++)
- if(isalpha(str[i]) ||
- isdigit(str[i]) ||
- str[i]=='?' || str[i]==':' || str[i]=='=' ||
- str[i]=='$' || str[i]=='-' || str[i]=='_' || str[i]=='.' || str[i]=='+' || str[i]=='!' ||
- str[i]=='*' || str[i]=='(' || str[i]==')' || str[i]==',' || str[i]==''')
- copy[j++]=str[i];
- else
- {
- unsigned int val=str[i];
- copy[j]='%';
- if(val%16>9)
- copy[j+2]=val%16+'A'-10;
- else
- copy[j+2]=val%16+'0';
- val/=16;
- if(val%16>9)
- copy[j+1]=val%16+'A'-10;
- else
- copy[j+1]=val%16+'0';
- j+=3;
- }
- copy[j]=0;
- return(copy);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Generate a hash value for a string.
- char *MakeHash Returns a string that can be used as the hashed string.
- const char *args The arguments.
- ++++++++++++++++++++++++++++++++++++++*/
- char *MakeHash(const char *args)
- {
- char md5[17];
- char *hash,*p;
- struct MD5Context ctx;
- /* Initialize the computation context. */
- MD5Init (&ctx);
- /* Process whole buffer but last len % 64 bytes. */
- MD5Update (&ctx, args, strlen(args));
- /* Put result in desired memory area. */
- MD5Final (md5, &ctx);
- md5[17]=0;
- hash=Base64Encode(md5,16);
- for(p=hash;*p;p++)
- if(*p=='/')
- *p='-';
- else if(*p=='=')
- *p=0;
- return(hash);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Convert the time into an RFC 822 compliant date.
- char *RFC822Date Returns a pointer to a fixed string containing the date.
- long t The time.
- int utc Set to true to get Universal Time, else localtime.
- ++++++++++++++++++++++++++++++++++++++*/
- char *RFC822Date(long t,int utc)
- {
- static char *week[7]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
- static char *month[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
- static char value[2][32];
- static int which=0;
- struct tm *tim;
- if(utc)
- tim=gmtime(&t);
- else
- {
- tim=localtime(&t);
- if(tim->tm_isdst<0)
- {tim=gmtime(&t);utc=1;}
- }
- which^=1;
- /* Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 */
- sprintf(value[which],"%3s, %02d %3s %4d %02d:%02d:%02d %s",
- week[tim->tm_wday],
- tim->tm_mday,
- month[tim->tm_mon],
- tim->tm_year+1900,
- tim->tm_hour,
- tim->tm_min,
- tim->tm_sec,
- #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
- utc?"GMT":tim->tm_zone
- #elif defined(__CYGWIN__)
- utc?"GMT":_tzname[tim->tm_isdst>0]
- #else
- utc?"GMT":tzname[tim->tm_isdst>0]
- #endif
- );
- return(value[which]);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Convert a string representing a date into a time.
- long DateToTimeT Returns the time.
- const char *date The date string.
- ++++++++++++++++++++++++++++++++++++++*/
- long DateToTimeT(const char *date)
- {
- static char *month[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
- int year,day,hour,min,sec;
- char monthstr[16];
- long retval=0;
- if(sscanf(date,"%*s %d %s %d %d:%d:%d",&day,monthstr,&year,&hour,&min,&sec)==6 ||
- sscanf(date,"%*s %d-%3s-%d %d:%d:%d",&day,monthstr,&year,&hour,&min,&sec)==6 ||
- sscanf(date,"%*s %3s %d %d:%d:%d %d",monthstr,&day,&hour,&min,&sec,&year)==6)
- {
- struct tm tim;
- int mon;
- for(mon=0;mon<12;mon++)
- if(!strcmp(monthstr,month[mon]))
- break;
- tim.tm_sec=sec;
- tim.tm_min=min;
- tim.tm_hour=hour;
- tim.tm_mday=day;
- tim.tm_mon=mon;
- if(year<38)
- tim.tm_year=year+100;
- else if(year<100)
- tim.tm_year=year;
- else
- tim.tm_year=year-1900;
- tim.tm_isdst=0;
- retval=mktime(&tim);
- if(retval==-1)
- retval=0;
- }
- else if(sscanf(date,"%ld %1s",&retval,monthstr)==1)
- ;
- return(retval);
- }
- /*+ The conversion from a 6 bit value to an ASCII character. +*/
- static char base64[64]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
- 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
- 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
- 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'};
- /*++++++++++++++++++++++++++++++++++++++
- Decode a base 64 string.
- char *Base64Decode Return a malloced string containing the decoded version.
- const char *str The string to be decoded.
- int *l Returns the length of the decoded string.
- ++++++++++++++++++++++++++++++++++++++*/
- char *Base64Decode(const char *str,int *l)
- {
- int le=strlen(str);
- char *decoded=(char*)malloc(le+1);
- int i,j,k;
- while(str[le-1]=='=')
- le--;
- *l=3*(le/4)+(le%4)-1+!(le%4);
- for(j=0;j<le;j++)
- for(k=0;k<64;k++)
- if(base64[k]==str[j])
- {decoded[j]=k;break;}
- for(i=j=0;j<(le+4);i+=3,j+=4)
- {
- unsigned long s=0;
- for(k=0;k<4;k++)
- if((j+k)<le)
- s|=((unsigned long)decoded[j+k]&0xff)<<(18-6*k);
- for(k=0;k<3;k++)
- if((i+k)<*l)
- decoded[i+k]=(char)((s>>(16-8*k))&0xff);
- }
- decoded[*l]=0;
- return(decoded);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Encode a string into base 64.
- char *Base64Encode Return a malloced string containing the encoded version.
- const char *str The string to be encoded.
- int l The length of the string to be encoded.
- ++++++++++++++++++++++++++++++++++++++*/
- char *Base64Encode(const char *str,int l)
- {
- int le=4*(l/3)+(l%3)+!!(l%3);
- char *encoded=(char*)malloc(4*(le/4)+4*!!(le%4)+1);
- int i,j,k;
- for(i=j=0;i<(l+3);i+=3,j+=4)
- {
- unsigned long s=0;
- for(k=0;k<3;k++)
- if((i+k)<l)
- s|=((unsigned long)str[i+k]&0xff)<<(16-8*k);
- for(k=0;k<4;k++)
- if((j+k)<le)
- encoded[j+k]=(char)((s>>(18-6*k))&0x3f);
- }
- for(j=0;j<le;j++)
- encoded[j]=base64[(int)encoded[j]];
- for(;j%4;j++)
- encoded[j]='=';
- encoded[j]=0;
- return(encoded);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Make the input string safe to output as HTML ( not < > & " ).
- char* HTMLString Returns a safe HTML string.
- const char* c A non-safe HTML string.
- ++++++++++++++++++++++++++++++++++++++*/
- char* HTMLString(const char* c)
- {
- int i=0,j=0,len=256-5; /* 5 is the longest possible inserted amount */
- char* ret=(char*)malloc(257);
- do
- {
- for(;j<len && c[i];i++)
- switch(c[i])
- {
- case '<':
- ret[j++]='&';
- ret[j++]='l';
- ret[j++]='t';
- ret[j++]=';';
- break;
- case '>':
- ret[j++]='&';
- ret[j++]='g';
- ret[j++]='t';
- ret[j++]=';';
- break;
- case '"':
- ret[j++]='&';
- ret[j++]='q';
- ret[j++]='u';
- ret[j++]='o';
- ret[j++]='t';
- ret[j++]=';';
- break;
- case '&':
- ret[j++]='&';
- ret[j++]='a';
- ret[j++]='m';
- ret[j++]='p';
- ret[j++]=';';
- break;
- default:
- ret[j++]=c[i];
- }
- if(c[i]) /* Not finished */
- {
- ret=(char*)realloc((void*)ret,len+256+5);
- len+=256;
- }
- }
- while(c[i]);
- ret[j]=0;
- return(ret);
- }