ftp.nice.ch/pub/next/unix/text/rtf.N.bsd.tar.gz#/rtf-utilities/rtfopen.c

This is rtfopen.c in view mode; [Download] [Up]

/*
 * RTF utilities: use rtfopen() and RTFopen() to obtain
 * a file descriptor or FILE pointer (respectively) to the
 * plain-text of a file.  If the file contains RTF text
 * or is an RTFD-style directory, a filtered version is created
 * in a temporary file, and pointers to it are returned.
 * Otherwise, the original (non-RTF) file is returned.
 *
 * Note that these routines, while useful in a NeXTSTEP or other
 * RTF-intensive context, are special cases of what needs to become
 * a much more general mechanism for querying a data source to ascertain
 * qualitative information about its contents, and then interpose
 * arbitrary data-casting filters (e.g., "open as English",
 * "open as 8KHz 16-bit linear mono audio", etc).
 *
 * Michael Hawley
 * MIT Media Laboratory
 * 20 Ames Street
 * Cambridge, MA 02139
 * mike@media-lab.mit.edu
 *
 * Please send me any improvements.
 */

char *rtf_ascii = "/usr/local/bin/rtf-ascii";
char *rtf_flags = "";  /* e.g., use "-C" for C files, etc */
int  was_rtf = 0;      /* set after rtfopen; true if file had RTF in it */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#include <stdio.h>

   static
   isDirectory(char *f){ // true if 'f' is directory
	struct stat b;
	stat(f, &b);
	return b.st_mode & S_IFDIR;
   }

   isrtf(int fd){ // true if file 'fd' contains rtf text */
	char s[6], *rtf="{\\rtf";
	s[sizeof(s)-1] = '\0';
	read(fd,s,sizeof(s)-1);
	lseek(fd,(long)0,0);
	return !strcmp(s,rtf);
   }

   isRTF(char *f){ // true if 'f' is RTF or .rtfd wrapper
	int fd, r=0;
        if (isDirectory(f)){ // is it a NeXT3.0 RTF wrapper?
            char t[1024];
            sprintf(t,"%s/%s",f,"TXT.rtf");
            return access(t,0)==0;
        }
        if ((fd = open(f,0)) > 0) r = isrtf(fd), close(fd);
	return r;
   }

rtfopen(name, flags, mode, tmp)
    char *name, *tmp;
    int flags, mode;
/*
 * See 'RTFopen()'.  This call returns a file descriptor, not a FILE pointer.
 */
{
    int f = 0, tn;
    char t[1024] = "/tmp/ascii", s[1024];

    was_rtf = 0;
    if (!isRTF((char *)name)) return open(name,flags,mode);
    was_rtf = 1;
    if (tmp && *tmp) strcpy(t,tmp);
    NXGetTempFilename(t,tn=strlen(t)); t[tn+6] = '\0';
    sprintf(s,"%s %s %s > %s",rtf_ascii,rtf_flags,name,t);
    if (!system(s))
        f = open(t,flags,mode);
    remove(t);	// deferred removal
    return f;
}

FILE *
RTFopen(name,mode,tmp)
    char *name, *mode, *tmp;
/*
 * Open 'name' for reading (NB: mode is ignored)
 * and if it contains RTF text, filter it away
 * by writing the plaintext into a temporary file.
 * If 'tmp' is given, it will contain the path prefix
 * to use when creating the temporary file (it is "/tmp/ascii" by default).
 */
{
    int fd = rtfopen(name,O_RDONLY,0,tmp);
    return fd>0? fdopen(fd,"r") : (FILE *)0;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.