This is XImageURL.m in view mode; [Download] [Up]
/* -*-C-*-
*******************************************************************************
*
* File: XImageURL.m
* RCS: $Header: /usr/local/lib/cvs/EnhanceMail/XImageURL.m,v 1.1.1.11 1996/06/25 13:44:23 cedman Exp $
* Description:
* Author: Carl Edman
* Created: Fri Oct 20 14:47:00 1995
* Modified: Mon Jun 24 10:26:29 1996 (Carl Edman) cedman@capitalist.princeton.edu
* Language: C
* Package: N/A
* Status: Experimental (Do Not Distribute)
*
* (C) Copyright 1995, but otherwise this file is perfect freeware.
*
*******************************************************************************
*/
#import <libc.h>
#import "EnhanceMail.h"
#import "XImageURL.h"
#import "Preferences.h"
#import "regexp.h"
#include <netdb.h>
#define MSG_OPEN_EXTERNAL_ATTACHMENT NXLoadLocalizedStringFromTableInBundle("Alerts", nil, "Open External Attachment", NULL)
#define MSG_RETRIEVE_HTTP NXLocalizedStringFromTableInBundle("Localizable", EnhanceBundle, "Retrieving %s from %s via http...", NULL, Message for HTTP retrieval)
#define LOCALCOPY(to,from,len) { to=alloca(len+1); strncpy(to,from,len); to[len]='\0'; }
BOOL imagepathExpanded = NO;
static const char *imagepath[]=
{
"/tmp",
"~/Library/Mail/Images",
"/LocalLibrary/Mail/Images",
"/NextLibrary/Mail/Images",
"#/Images",
0
};
@implementation NXImage(XImageURL)
+ (BOOL)grabURL:(const char *)url to:(const char *)localpath
{
static regexp *ftprx=0;
static regexp *httprx=0;
if (!*url) return NO;
if (ftprx==0)
ftprx=regcomp("^ftp://([^:/ ]*(:[^/@ ]*)?@)?([^/]*/)(([^/]*/)*)([^/;]*)$");
if (regexec(ftprx,url))
{
char *host,*dir,*filename,*user,*pass,*userpass,*path;
id fetcher=[MimeFetcher new];
if (ftprx->startp[1]&&ftprx->startp[2])
{
LOCALCOPY(user,ftprx->startp[1],ftprx->startp[2]-ftprx->startp[1]);
LOCALCOPY(pass,ftprx->startp[2]+1,ftprx->endp[2]-ftprx->startp[2]-1);
userpass=alloca(strlen(user)+strlen(pass)+2);
sprintf(userpass,"%s %s",user,pass);
}
else if (ftprx->startp[1])
{
LOCALCOPY(user,ftprx->startp[1],ftprx->endp[1]-ftprx->startp[1]-1);
if (pass=index([fetcher anonUserPass],' ')) pass++; else pass="anonymous";
userpass=alloca(strlen(user)+strlen(pass)+2);
sprintf(userpass,"%s %s",user,pass);
}
else
{
const char *c=[fetcher anonUserPass];
userpass=strcpy(alloca(strlen(c)+1),c);
}
LOCALCOPY(host, ftprx->startp[3],ftprx->endp[3]-ftprx->startp[3]-1);
LOCALCOPY(dir, ftprx->startp[4],ftprx->endp[4]-ftprx->startp[4]-1);
LOCALCOPY(filename,ftprx->startp[6],ftprx->endp[6]-ftprx->startp[6]);
LOCALCOPY(path,localpath,strlen(localpath));
if ([fetcher ftpFrom:host directory:dir filename:filename mode:"binary" forUserPass:userpass to:path]==NO)
return NO;
if (access(path,R_OK)!=0)
return NO;
return YES;
}
if (httprx==0)
httprx=regcomp("^http://([^:/ ]*)(:[0-9]+)?(/[^;]*)$");
if (regexec(httprx,url))
{
char *hostname="localhost",*path="/",*port="80";
char buf[1024],*pos;
struct sockaddr_in http;
struct hostent *hp;
int totlen=-1,rcvlen=0,len;
int ifd=-1,ofd=-1;
BOOL success=NO;
Progressor *progress=nil;
if (EnhanceHTTPProxy && *EnhanceHTTPProxy)
{
strcpy(buf,EnhanceHTTPProxy);
strcat(buf,url);
if (!regexec(httprx,buf)) goto httpend;
}
if (httprx->startp[1])
LOCALCOPY(hostname,httprx->startp[1],httprx->endp[1]-httprx->startp[1]);
if (httprx->startp[2])
LOCALCOPY(port,httprx->startp[2]+1,httprx->endp[2]-httprx->startp[2]-1);
if (httprx->startp[3])
LOCALCOPY(path,httprx->startp[3],httprx->endp[3]-httprx->startp[3]);
sprintf(buf,MSG_RETRIEVE_HTTP,strrchr(path,'/')+1,hostname);
if ((progress=[Progressor newWithTitle:MSG_OPEN_EXTERNAL_ATTACHMENT message:buf])==nil) goto httpend;
[progress setShowProgress:NO];
[progress beginModalSession];
if ((hp = gethostbyname(hostname))==0) goto httpend;
bzero((char *)&http, sizeof(http));
bcopy(hp->h_addr,(char *)&http.sin_addr,hp->h_length);
http.sin_family = hp->h_addrtype;
http.sin_port = htons(atoi(port));
if ((ifd=socket(AF_INET, SOCK_STREAM, 0))==-1) goto httpend;
if (connect(ifd,(struct sockaddr *) &http,sizeof(http))==-1) goto httpend;
sprintf(buf,"GET %s HTTP/1.0\r\nUser-Agent: EnhanceMail/%s\r\nAccept: image/tiff\r\n\r\n",path,EnhanceVersion);
write(ifd,buf,strlen(buf));
pos=buf;
while(![progress cancelled]&&((len=read(ifd,pos,(buf+sizeof(buf))-pos))>0))
{
char *end=pos+len,*c,*d;
for(c=buf,d=buf;c<end;c++)
{
if (*c!='\n') continue;
c[0]='\0';
if ((c>buf)&&(c[-1]=='\r')) c[-1]='\0';
if (strncasecmp(d,"HTTP/1.0 ",9)==0)
{
if (atoi(d+9)!=200) goto httpend;
}
if (strncasecmp(d,"Content-Length: ",16)==0)
{
totlen=atoi(d+16);
[progress setMinValue:0];
[progress setMaxValue:totlen];
[progress setProgress:0];
[progress setShowProgress:YES];
}
if (*d=='\0')
{
if ((ofd=open(localpath,O_WRONLY|O_CREAT|O_TRUNC,0644))==-1)
goto httpend;
rcvlen=end-(c+1);
write(ofd,c+1,end-(c+1));
[progress setProgress:rcvlen];
while(![progress cancelled]&&((len=read(ifd,buf,sizeof(buf)))>0))
{
write(ofd,buf,len);
rcvlen+=len;
if (totlen>0) [progress setProgress:rcvlen];
}
success=(len==0)&&((totlen==rcvlen)||(totlen==-1));
goto httpend;
}
d=c+1;
}
pos=buf;
if (d>buf) while (d<end) *pos++=*d++;
}
httpend:
if (ifd!=-1) close(ifd);
if (ofd!=0) close(ofd);
if (progress!=nil) [progress endModalSession];
return success;
}
return NO;
}
+ (BOOL)grabURL:(const char *)url buffer:(char *)path
{
int i;
char *localname,*c;
if (!*url) return NO;
localname=strcpy(alloca(strlen(url)+1),url);
for(c=localname;*c;c++) if (*c=='/') *c='_';
if (imagepathExpanded==NO) imagepathExpanded=EnhancePaths(imagepath);
for(i=0;imagepath[i];i++)
{
sprintf(path,"%s/%s",imagepath[i],localname);
if (access(path,R_OK)==0) return YES;
}
for(i--;i>=0;i--) if (access(imagepath[i],R_OK|W_OK|X_OK)==0) break;
if (i<0) return NO;
sprintf(path,"%s/%s",imagepath[i],localname);
if (![self grabURL:url to:path])
{
int fd=open(path,O_WRONLY|O_CREAT|O_TRUNC,0644);
if (fd!=-1) close(fd);
return NO;
}
return YES;
}
+ (BOOL)grabURL:(const char *)url string:(SimpleString *)s
{
int fd;
char path[MAXPATHLEN+1];
if (tmpnam(path)==0) return NO;
if (![self grabURL:url to:path]) return NO;
if ((fd=open(path,O_RDONLY))==-1) return NO;
unlink(path);
[s appendFile:fd];
close(fd);
return YES;
}
- initURL:(const char *)url
{
char path[MAXPATHLEN+1];
struct stat buf;
if (![[self class] grabURL:url buffer:path]) return [self free];
if ((stat(path,&buf)==-1)||(buf.st_size==0)) return [self free];
return [self initFromFile:path];
}
- initNameInPath:(const char *)filename
{
int i;
char path[MAXPATHLEN+1];
struct stat buf;
if (imagepathExpanded==NO) imagepathExpanded=EnhancePaths(imagepath);
for(i=0;imagepath[i];i++)
{
sprintf(path,"%s/%s",imagepath[i],filename);
if (access(path,R_OK)==0) break;
}
if (!imagepath[i]) return [self free];
if ((stat(path,&buf)==-1)||(buf.st_size==0)) return [self free];
return [self initFromFile:path];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.