Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
48
cde/programs/dtmail/dtmailpr/Imakefile
Normal file
48
cde/programs/dtmail/dtmailpr/Imakefile
Normal file
@@ -0,0 +1,48 @@
|
||||
XCOMM $TOG: Imakefile /main/15 1998/08/05 13:24:40 mgreess $
|
||||
|
||||
#define CplusplusSource YES
|
||||
DEPEND_DEFINES = $(CXXDEPENDINCLUDES)
|
||||
EXTRA_LOAD_FLAGS = ExtraLoadFlags $(UNSHARED_CXXLIB)
|
||||
|
||||
INCLUDES = -I. -I../include -I../../dtcompat -I../../../. -I$(CDELIBSRC)
|
||||
|
||||
#ifndef DtMailDefines
|
||||
# define DtMailDefines
|
||||
#endif
|
||||
DEFINES = DtMailDefines
|
||||
|
||||
DEPLIBS = ../libDtMail/libDtMail.a DepDtClientLibs
|
||||
LOCAL_LIBRARIES = ../libDtMail/libDtMail.a DtClientLibs
|
||||
SYS_LIBRARIES = $(DYNLIBSYSLIB) $(ICONVSYSLIB) $(REGEXSYSLIB) -lm
|
||||
|
||||
#ifdef SunArchitecture
|
||||
# ifndef SUNPRODIR
|
||||
SUNPRO_DIR = /opt/SUNWspro
|
||||
# else
|
||||
SUNPRO_DIR = SUNPRODIR
|
||||
# endif
|
||||
|
||||
C++LIBPATH = -L$(SUNPRO_DIR)/lib
|
||||
|
||||
EXTRA_CCOPTIONS = -xstrconst -Xc -v
|
||||
# ifdef USE_SPRO_V3
|
||||
SPRO_V3_OPTIONS = -noex -USPRO_V2
|
||||
# ifdef DEBUGTREE
|
||||
SPRO_V3_OPTIONS += -xsb
|
||||
# endif /* DEBUGTREE */
|
||||
# else
|
||||
EXTRA_CCOPTIONS += -DSPRO_V2
|
||||
# endif /* USE_SPRO_V3 */
|
||||
|
||||
EXTRA_C++OPTIONS = +p +w $(SPRO_V3_OPTIONS)
|
||||
MT_LIBS = -i $(C++_LIB) -lm -lw -lc
|
||||
|
||||
SYS_LIBRARIES = -lintl -lnsl $(MT_LIBS) -lC
|
||||
#endif /* SunArchitecture */
|
||||
|
||||
SRCS = main.C message.C mailbox.C utils.C
|
||||
OBJS = main.o message.o mailbox.o utils.o
|
||||
|
||||
NormalCplusplusObjectRule()
|
||||
|
||||
ComplexCplusplusProgramTarget(dtmailpr)
|
||||
138
cde/programs/dtmail/dtmailpr/dmx.hh
Normal file
138
cde/programs/dtmail/dtmailpr/dmx.hh
Normal file
@@ -0,0 +1,138 @@
|
||||
/* $XConsortium: dmx.hh /main/5 1996/04/21 19:43:59 drk $ */
|
||||
|
||||
#ifndef _DMX_HH
|
||||
#define _DMX_HH
|
||||
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $:$
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement between
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
||||
* Sun's specific written approval. This document and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(sun) && defined(_XOPEN_SOURCE)
|
||||
#ifndef B_TRUE
|
||||
#define B_TRUE _B_TRUE
|
||||
#endif
|
||||
#ifndef B_FALSE
|
||||
#define B_FALSE _B_FALSE
|
||||
#endif
|
||||
#endif /* sun && _XOPEN_SOURCE */
|
||||
|
||||
#if defined(_AIX)
|
||||
#ifndef B_FALSE
|
||||
#define B_FALSE 0
|
||||
#endif
|
||||
#ifndef B_TRUE
|
||||
#define B_TRUE 1
|
||||
#endif
|
||||
#endif /* _AIX */
|
||||
|
||||
|
||||
|
||||
#include <DtMail/DtMail.hh>
|
||||
#include <DtMail/DtMailError.hh>
|
||||
#include <DtMail/DtMailValues.hh>
|
||||
#include <Dt/Dts.h>
|
||||
|
||||
extern const char *const dmxversion;
|
||||
|
||||
enum DmxHeaderType { MSGLIST, MSGHEADER, NUMHDRTYPES };
|
||||
enum DmxHeaders
|
||||
{
|
||||
DMXFROM,
|
||||
DMXSUBJ,
|
||||
DMXCLENGTH,
|
||||
DMXSTATUS,
|
||||
DMXDATE,
|
||||
DMXTO,
|
||||
DMXV3CHARSET,
|
||||
DMXCONTENTTYPE,
|
||||
DMXNUMHDRS
|
||||
};
|
||||
|
||||
// This is undoubtedly illegal, unethical, and immoral. So sue me.
|
||||
#if !defined(SunOS) && !defined(USL) && !defined(_AIX) && !defined(__uxp__)
|
||||
#undef boolean_t
|
||||
typedef enum { B_FALSE, B_TRUE } boolean_t;
|
||||
#endif // SunOS
|
||||
|
||||
// utils
|
||||
char *convertValueToString (DtMailValueSeq *value, int s);
|
||||
boolean_t handleError (DtMailEnv &, char *);
|
||||
char *formatHeader (DtMailHeaderLine &, enum DmxHeaderType);
|
||||
|
||||
class DmxMsg
|
||||
{
|
||||
public:
|
||||
DmxMsg (void);
|
||||
|
||||
char *printHeader (enum DmxHeaderType);
|
||||
void display (void);
|
||||
void setHandle (DtMailMessageHandle &);
|
||||
void setHeader (DtMailHeaderLine &);
|
||||
void setMessage (DtMail::Message *);
|
||||
void setInfo (char *);
|
||||
void parse (void);
|
||||
void getFlags (void);
|
||||
|
||||
|
||||
DtMailMessageHandle msgHandle;
|
||||
DtMailHeaderLine msgHeader;
|
||||
DtMail::Message *message;
|
||||
|
||||
DtMail::BodyPart **bodyParts;
|
||||
int numBPs;
|
||||
|
||||
char *addlInfo;
|
||||
boolean_t cachedValues;
|
||||
boolean_t isCurrent;
|
||||
boolean_t hasAttachments;
|
||||
boolean_t isNew;
|
||||
// other flags for status (read, unopened, etc.)
|
||||
};
|
||||
|
||||
|
||||
class DmxMailbox
|
||||
{
|
||||
public:
|
||||
DmxMailbox (void);
|
||||
|
||||
DtMail::MailBox *mbox;
|
||||
int messageCount;
|
||||
int newMessages;
|
||||
int firstNew;
|
||||
char *name;
|
||||
|
||||
void loadMessages (void);
|
||||
void createHeaderRequest (DtMailHeaderRequest &);
|
||||
void printMailboxInfo (void);
|
||||
|
||||
DmxMsg msg [1024];
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _DMX_HH
|
||||
185
cde/programs/dtmail/dtmailpr/mailbox.C
Normal file
185
cde/programs/dtmail/dtmailpr/mailbox.C
Normal file
@@ -0,0 +1,185 @@
|
||||
/* $XConsortium: mailbox.C /main/4 1996/04/21 19:44:02 drk $ */
|
||||
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $:$
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement between
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
||||
* Sun's specific written approval. This document and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "dmx.hh"
|
||||
|
||||
|
||||
DmxMailbox::DmxMailbox (void)
|
||||
{
|
||||
mbox = NULL;
|
||||
newMessages = 0;
|
||||
messageCount = 0;
|
||||
firstNew = 0;
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMailbox::loadMessages (void)
|
||||
{
|
||||
DtMailEnv env;
|
||||
boolean_t moreMessages = B_TRUE;
|
||||
|
||||
// open the mailbox
|
||||
// (O_RDONLY for now)
|
||||
mbox->open (env, /* DtMailEnv */
|
||||
DTM_FALSE, /* auto_create */
|
||||
O_RDONLY, /* open(2) flag */
|
||||
(mode_t) 0, /* create(2) mode */
|
||||
DTM_FALSE, /* lock_flag */
|
||||
DTM_TRUE /* auto_parse */
|
||||
);
|
||||
|
||||
if (handleError (env, "open mailbox") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
// get the first message handle
|
||||
DtMailMessageHandle first = NULL, next = NULL, prev = NULL;
|
||||
DtMailHeaderRequest request;
|
||||
DtMailHeaderLine hdrline;
|
||||
int i = 1;
|
||||
DtMail::Message *m = NULL; // temporary
|
||||
|
||||
createHeaderRequest (request);
|
||||
|
||||
first = mbox->getFirstMessageSummary (env, request, hdrline);
|
||||
|
||||
if (handleError (env, "get first msg summary") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
if (first == NULL)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"loadMessages: error w/1st message...exiting.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
// this makes hash of the caching strategy, but oh well....
|
||||
m = mbox->getMessage (env, first);
|
||||
if (handleError (env, "get first msg") == B_TRUE)
|
||||
exit (1);
|
||||
msg [i].setMessage (m);
|
||||
|
||||
prev = first;
|
||||
|
||||
msg [i].setHandle (first);
|
||||
msg [i].setHeader (hdrline);
|
||||
|
||||
while (moreMessages == B_TRUE)
|
||||
{
|
||||
next = mbox->getNextMessageSummary (env, prev,
|
||||
request, hdrline);
|
||||
|
||||
if (next == NULL)
|
||||
{
|
||||
moreMessages = B_FALSE;
|
||||
if (handleError (env, "msgLoop") == B_TRUE)
|
||||
exit (1);
|
||||
break; // break out if error
|
||||
} else {
|
||||
i++;
|
||||
msg [i].setHandle (next);
|
||||
msg [i].setHeader (hdrline);
|
||||
}
|
||||
|
||||
prev = next;
|
||||
}
|
||||
|
||||
messageCount = i;
|
||||
|
||||
|
||||
// fill in the remaining message structures .. temporary, honest!
|
||||
for (int j = 1; j <= messageCount; j++)
|
||||
{
|
||||
m = mbox->getMessage (env, msg [j].msgHandle);
|
||||
if (handleError (env, "getMessage loop") == B_TRUE)
|
||||
{
|
||||
printf ("fatal error...bailing...\n");
|
||||
exit (1);
|
||||
}
|
||||
msg [j].setMessage (m);
|
||||
|
||||
char tmp [100];
|
||||
sprintf (tmp, "%d", j); // ick
|
||||
msg [j].setInfo (tmp);
|
||||
|
||||
msg[j].getFlags ();
|
||||
if (msg[j].isNew == B_TRUE)
|
||||
{
|
||||
newMessages++;
|
||||
if (firstNew == 0)
|
||||
{
|
||||
firstNew = j;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// no new messages -- start with first message in mailbox
|
||||
if (firstNew == 0)
|
||||
firstNew = 1;
|
||||
|
||||
// free header request structure
|
||||
int k;
|
||||
// this assumes that you have allocated all of the possible headers
|
||||
// in the enum DmxHeaders -- a bad assumption, but currently true
|
||||
for (k = 0; k < DMXNUMHDRS; k++)
|
||||
{
|
||||
free (request.header_name [k]);
|
||||
}
|
||||
delete request.header_name;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMailbox::createHeaderRequest (DtMailHeaderRequest &request)
|
||||
{
|
||||
// set up default headers
|
||||
request.number_of_names = DMXNUMHDRS;
|
||||
request.header_name = new (char* [DMXNUMHDRS]);
|
||||
request.header_name[DMXFROM] = strdup(DtMailMessageSender);
|
||||
request.header_name[DMXSUBJ] = strdup(DtMailMessageSubject);
|
||||
request.header_name[DMXDATE] = strdup(DtMailMessageReceivedTime);
|
||||
request.header_name[DMXCLENGTH] = strdup(DtMailMessageContentLength);
|
||||
request.header_name[DMXSTATUS] = strdup(DtMailMessageStatus);
|
||||
request.header_name[DMXTO] = strdup(DtMailMessageTo);
|
||||
request.header_name[DMXV3CHARSET] = strdup(DtMailMessageV3charset);
|
||||
request.header_name[DMXCONTENTTYPE] = strdup(DtMailMessageContentType);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMailbox::printMailboxInfo (void)
|
||||
{
|
||||
if (newMessages > 0)
|
||||
{
|
||||
printf ("\"%s\": %d messages %d new\n",
|
||||
name, messageCount, newMessages);
|
||||
} else {
|
||||
printf ("\"%s\": %d messages\n",
|
||||
name, messageCount);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
210
cde/programs/dtmail/dtmailpr/main.C
Normal file
210
cde/programs/dtmail/dtmailpr/main.C
Normal file
@@ -0,0 +1,210 @@
|
||||
/* $TOG: main.C /main/7 1998/10/26 17:19:37 mgreess $ */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include "dmx.hh"
|
||||
#include <locale.h>
|
||||
#include <sys/param.h>
|
||||
// #include <Dt/DtNlUtils.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void Dt_nlInit( void );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include <Dt/EnvControlP.h>
|
||||
#include <Dt/DtPStrings.h>
|
||||
|
||||
/*
|
||||
* globals
|
||||
*/
|
||||
|
||||
gid_t _originalEgid; // startup effective gid
|
||||
gid_t _originalRgid; // startup real gid
|
||||
|
||||
void
|
||||
enableGroupPrivileges(void *)
|
||||
{
|
||||
(void) setgid(_originalEgid);
|
||||
}
|
||||
|
||||
void
|
||||
disableGroupPrivileges(void *)
|
||||
{
|
||||
(void) setgid(_originalRgid);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
// parse command-line options
|
||||
int c;
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
char *ffile = NULL;
|
||||
int aflag = 0, pgflag = 0;
|
||||
int errflag = 0;
|
||||
|
||||
// we have to be set-gid to group "mail" when opening and storing
|
||||
// folders. But we don't want to do everything as group mail.
|
||||
// here we record our original gid, and set the effective gid
|
||||
// back the the real gid. We'll set it back when we're dealing
|
||||
// with folders...
|
||||
//
|
||||
_originalEgid = getegid(); // remember effective group ID
|
||||
_originalRgid = getgid(); // remember real group ID
|
||||
disableGroupPrivileges((void *)0); // disable group privileges from
|
||||
// here on
|
||||
|
||||
/*
|
||||
* To make DtDts*() function correctly, we have to call
|
||||
* DtInitialize() or DtAppInitialize(). But they require Widget....
|
||||
* Instead, just call Dt_nlInit() that is an internal function of
|
||||
* libDtSvc.a. This is a temporary hack.....
|
||||
*/
|
||||
_DtEnvControl(DT_ENV_SET);
|
||||
setlocale( LC_ALL, "" );
|
||||
Dt_nlInit();
|
||||
|
||||
while ((c = getopt(argc, argv, "f:aph?")) != EOF)
|
||||
switch (c)
|
||||
{
|
||||
case 'p':
|
||||
pgflag++;
|
||||
//printf ("Print each message on its own page\n");
|
||||
break;
|
||||
case 'a':
|
||||
aflag++;
|
||||
//printf ("Strip attachments\n");
|
||||
break;
|
||||
case 'f':
|
||||
ffile = optarg;
|
||||
//printf ("Input file is: %s\n", ffile);
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
errflag++;
|
||||
break;
|
||||
default:
|
||||
errflag++;
|
||||
}
|
||||
if (errflag)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-p] [-a] [-f <filename>] \n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
//for ( ; optind < argc; optind++)
|
||||
//(void)printf("%s\n", argv[optind]);
|
||||
|
||||
|
||||
// create DtMail session
|
||||
|
||||
DtMailEnv dmxenv;
|
||||
DtMail::Session *session;
|
||||
|
||||
DmxMailbox mbox;
|
||||
|
||||
session = new DtMail::Session (dmxenv, "dtmailpr");
|
||||
|
||||
|
||||
if (handleError (dmxenv, "new session") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
if (session == NULL)
|
||||
{
|
||||
fprintf (stderr, "Error opening session...exiting.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
// Register all callbacks the backend may have to deal with
|
||||
session->registerDisableGroupPrivilegesCallback(disableGroupPrivileges,
|
||||
(void *)0);
|
||||
session->registerEnableGroupPrivilegesCallback(enableGroupPrivileges,
|
||||
(void *)0);
|
||||
|
||||
// initialize typing system (will go away eventually)
|
||||
DtDtsLoadDataTypes ();
|
||||
|
||||
// temporary hack, until I'm sure that buffer objects are working
|
||||
char buf [BUFSIZ];
|
||||
int n = 0;
|
||||
char *name;
|
||||
FILE *msgFile=NULL;
|
||||
|
||||
if (ffile == NULL)
|
||||
{
|
||||
static char *tmpdir = new char[MAXPATHLEN+1];
|
||||
|
||||
sprintf(
|
||||
tmpdir,
|
||||
"%s/%s",
|
||||
getenv("HOME"),
|
||||
DtPERSONAL_TMP_DIRECTORY);
|
||||
|
||||
name = tempnam(tmpdir, "dtmpr");
|
||||
if ((msgFile = fopen (name, "w+")) == NULL)
|
||||
{
|
||||
perror ("tmpfile");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
while ( (n = read (fileno (stdin), buf, BUFSIZ)) > 0)
|
||||
{
|
||||
if (write (fileno (msgFile), buf, n) != n)
|
||||
{
|
||||
perror ("write");
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
perror ("read");
|
||||
}
|
||||
|
||||
fclose (msgFile);
|
||||
delete [] tmpdir;
|
||||
|
||||
} else {
|
||||
name = ffile;
|
||||
}
|
||||
DtMail::MailBox *mailbox = NULL;
|
||||
|
||||
// try to construct mbox
|
||||
mailbox = session->mailBoxConstruct (
|
||||
dmxenv,
|
||||
DtMailFileObject,
|
||||
name,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (handleError (dmxenv, "new DtMail::MailBox") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
mbox.name = new char [strlen (name) +1];
|
||||
strcpy (mbox.name, name);
|
||||
|
||||
mbox.mbox = mailbox;
|
||||
mbox.loadMessages ();
|
||||
|
||||
int m = 0;
|
||||
|
||||
for (m = 1; m <= mbox.messageCount; m++)
|
||||
{
|
||||
mbox.msg[m].getFlags ();
|
||||
mbox.msg[m].display ();
|
||||
if (m < mbox.messageCount) {
|
||||
if (pgflag) {
|
||||
printf ("");
|
||||
} else {
|
||||
printf ("\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
477
cde/programs/dtmail/dtmailpr/message.C
Normal file
477
cde/programs/dtmail/dtmailpr/message.C
Normal file
@@ -0,0 +1,477 @@
|
||||
/* $TOG: message.C /main/9 1998/07/24 16:08:20 mgreess $
|
||||
*
|
||||
* (c) Copyright 1996 Digital Equipment Corporation.
|
||||
* (c) Copyright 1996 Hewlett-Packard Company.
|
||||
* (c) Copyright 1996 International Business Machines Corp.
|
||||
* (c) Copyright 1994,1996 Sun Microsystems, Inc.
|
||||
* (c) Copyright 1996 Novell, Inc.
|
||||
* (c) Copyright 1996 FUJITSU LIMITED.
|
||||
* (c) Copyright 1996 Hitachi.
|
||||
*/
|
||||
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement between
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
||||
* Sun's specific written approval. This document and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include "dmx.hh"
|
||||
// For CHARSET
|
||||
#include <DtHelp/LocaleXlate.h>
|
||||
#include <locale.h>
|
||||
#if !defined(USL) && !defined(__uxp__)
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <EUSCompat.h>
|
||||
#endif
|
||||
#include "utils/str_utils.h"
|
||||
|
||||
|
||||
DmxMsg::DmxMsg (void)
|
||||
{
|
||||
// initialize everything
|
||||
message = NULL;
|
||||
addlInfo = NULL;
|
||||
numBPs = 0;
|
||||
cachedValues = B_FALSE;
|
||||
isCurrent = B_FALSE;
|
||||
hasAttachments = B_FALSE;
|
||||
isNew = B_FALSE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMsg::setHandle (DtMailMessageHandle &h)
|
||||
{
|
||||
msgHandle = h;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMsg::setHeader (DtMailHeaderLine &h)
|
||||
{
|
||||
msgHeader = h;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMsg::setMessage (DtMail::Message *m)
|
||||
{
|
||||
message = m;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMsg::setInfo (char *info)
|
||||
{
|
||||
addlInfo = strdup (info);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMsg::getFlags (void)
|
||||
{
|
||||
DtMailEnv env;
|
||||
DtMailBoolean flagState;
|
||||
|
||||
memset (&env, '\0', sizeof (DtMailEnv));
|
||||
flagState = DTM_FALSE;
|
||||
|
||||
|
||||
|
||||
|
||||
flagState = message->flagIsSet (env, DtMailMessageMultipart);
|
||||
if (handleError (env, "msg: multipart?") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
if (flagState == DTM_TRUE)
|
||||
{
|
||||
hasAttachments = B_TRUE;
|
||||
} else {
|
||||
hasAttachments = B_FALSE;
|
||||
}
|
||||
|
||||
flagState = message->flagIsSet (env, DtMailMessageNew);
|
||||
if (handleError (env, "msg: new?") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
if (flagState == DTM_TRUE)
|
||||
{
|
||||
isNew = B_TRUE;
|
||||
} else {
|
||||
isNew = B_FALSE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char *
|
||||
DmxMsg::printHeader (enum DmxHeaderType htype)
|
||||
{
|
||||
DtMailEnv env;
|
||||
char *status, *indicator;
|
||||
|
||||
if (isCurrent == B_TRUE)
|
||||
{
|
||||
indicator = ">";
|
||||
} else {
|
||||
indicator = " ";
|
||||
}
|
||||
|
||||
if (isNew == B_TRUE)
|
||||
{
|
||||
status = "N";
|
||||
} else {
|
||||
status = "O"; // how about "unread" ??
|
||||
}
|
||||
|
||||
if (hasAttachments == B_TRUE)
|
||||
{
|
||||
indicator = "@";
|
||||
}
|
||||
|
||||
// the addlInfo string is any extra info needed by the
|
||||
// viewer, such as a message number
|
||||
|
||||
char *buffer = new char [1024];
|
||||
memset (buffer, 0, 1024);
|
||||
|
||||
switch (htype)
|
||||
{
|
||||
case MSGLIST:
|
||||
sprintf (buffer, "%s%s%s %s",
|
||||
indicator, status, addlInfo,
|
||||
formatHeader (msgHeader, MSGLIST));
|
||||
break;
|
||||
case MSGHEADER:
|
||||
sprintf (buffer, "%s",
|
||||
formatHeader (msgHeader, MSGHEADER));
|
||||
break;
|
||||
default:
|
||||
printf ("error in DmxMsg::display\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DmxMsg::display (void)
|
||||
{
|
||||
DtMailEnv env;
|
||||
boolean_t FirstIsText = B_FALSE;
|
||||
DtMail::BodyPart *firstPart = NULL, *nextpart = NULL;
|
||||
char *type;
|
||||
char *description = NULL;
|
||||
char *sunDataDescription = NULL;
|
||||
char *name = NULL;
|
||||
void * contents = NULL;
|
||||
unsigned long length = 0;
|
||||
int mode = 0;
|
||||
char *buf = NULL;
|
||||
// For CHARSET
|
||||
char *mime_cs = NULL, *from_cs = NULL, *to_cs = NULL;
|
||||
char *v3_cs = new char [64];
|
||||
|
||||
if (cachedValues != B_TRUE)
|
||||
parse (); // read in body part info
|
||||
|
||||
firstPart = bodyParts [0];
|
||||
|
||||
firstPart->getContents(env,
|
||||
(const void **) &contents,
|
||||
&length,
|
||||
NULL, //type
|
||||
NULL, //name
|
||||
NULL, //mode
|
||||
NULL); //description
|
||||
|
||||
if (handleError (env, "getContents") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
// For CHARSET
|
||||
|
||||
DtMailValueSeq value;
|
||||
boolean_t err = B_FALSE;
|
||||
|
||||
// Get the bodypart's charset - Try MIME first then V3
|
||||
firstPart->getHeader(env, DtMailMessageContentType, DTM_TRUE, value);
|
||||
if (env.isNotSet()) {
|
||||
mime_cs = firstPart->csFromContentType(value);
|
||||
} else {
|
||||
env.clear();
|
||||
value.clear();
|
||||
firstPart->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value);
|
||||
if (env.isNotSet()) {
|
||||
strcpy(v3_cs, *(value[0]));
|
||||
} else {
|
||||
err = B_TRUE;
|
||||
env.clear();
|
||||
value.clear();
|
||||
}
|
||||
}
|
||||
// If cannot obtain bodypart's charset header, then maybe this message
|
||||
// has only one bodypart, then in this case the charset header maybe
|
||||
// among the message's envelope (main message headers).
|
||||
// Get the envelope of the message (in order to access the headers)
|
||||
DtMail::Envelope *envelope = NULL;
|
||||
if (err == B_TRUE) {
|
||||
envelope = message->getEnvelope(env);
|
||||
err = B_FALSE;
|
||||
#ifdef DEBUG
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: Looking at main message header\n");
|
||||
#endif
|
||||
}
|
||||
if (envelope != NULL) {
|
||||
// Check for MIME charset header and then for V3 charset header
|
||||
envelope->getHeader(env, DtMailMessageContentType, DTM_TRUE, value);
|
||||
if (env.isNotSet()) {
|
||||
mime_cs = firstPart->csFromContentType(value);
|
||||
} else {
|
||||
err = B_TRUE;
|
||||
env.clear();
|
||||
}
|
||||
if (mime_cs == NULL || err == B_TRUE) {
|
||||
value.clear();
|
||||
envelope->getHeader(env, DtMailMessageV3charset, DTM_TRUE, value);
|
||||
if (env.isNotSet()) {
|
||||
strcpy(v3_cs, *(value[0]));
|
||||
} else {
|
||||
err = B_TRUE;
|
||||
env.clear();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: envelope is null\n");
|
||||
#endif
|
||||
env.clear();
|
||||
}
|
||||
|
||||
// Default codeset in case mime_cs and v3_cs are both null.
|
||||
if ((mime_cs == NULL) && (strlen(v3_cs) == 0)) {
|
||||
char *ret = NULL;
|
||||
firstPart->DtXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,
|
||||
setlocale(LC_CTYPE, NULL),
|
||||
NULL,
|
||||
NULL,
|
||||
&ret);
|
||||
strcpy(v3_cs, "DEFAULT");
|
||||
strcat(v3_cs, ".");
|
||||
strcat(v3_cs, ret);
|
||||
if (ret)
|
||||
free(ret);
|
||||
}
|
||||
|
||||
// Get iconv from and to codeset and do conversion.
|
||||
int converted = 0;
|
||||
if (mime_cs) {
|
||||
from_cs = firstPart->csToConvName(mime_cs);
|
||||
#ifdef DEBUG
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: mime_cs = %s\n", mime_cs);
|
||||
#endif
|
||||
} else {
|
||||
from_cs = firstPart->csToConvName(v3_cs);
|
||||
#ifdef DEBUG
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: v3_cs = %s\n", v3_cs);
|
||||
#endif
|
||||
}
|
||||
to_cs = firstPart->locToConvName();
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( from_cs == NULL )
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs is NULL\n");
|
||||
else
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: from_cs = %s\n", from_cs);
|
||||
|
||||
if ( to_cs == NULL )
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs is NULL\n");
|
||||
else
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: to_cs = %s\n", to_cs);
|
||||
#endif
|
||||
|
||||
if ( from_cs && to_cs ) {
|
||||
if ( strcasecmp(from_cs, to_cs) != 0 ) {
|
||||
converted = firstPart->csConvert((char **)&contents, length, 0, from_cs, to_cs);
|
||||
#ifdef DEBUG
|
||||
env.logError(DTM_FALSE, "DEBUG dtmailpr: converted = %d\n", converted);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if ( mime_cs )
|
||||
free ( mime_cs );
|
||||
if ( from_cs )
|
||||
free( from_cs );
|
||||
if ( to_cs )
|
||||
free ( to_cs );
|
||||
|
||||
// End of For CHARSET
|
||||
|
||||
|
||||
buf = new char [length + 1];
|
||||
memset (buf, 0, (size_t) length + 1);
|
||||
|
||||
// have to "seek" length bytes into the
|
||||
// contents buffer
|
||||
memmove (buf, contents, (size_t) length);
|
||||
buf [length] = '\0'; // null-terminate
|
||||
// that puppy
|
||||
|
||||
// For CHARSET
|
||||
if (converted && contents)
|
||||
free(contents);
|
||||
|
||||
char *numbuf = new char [10241];
|
||||
memset (numbuf, 0, 1024);
|
||||
|
||||
#ifdef NEVER
|
||||
// Don't want "Message 1:" appearing in print output
|
||||
sprintf (numbuf, "Messsage %s:\n%s\n",
|
||||
addlInfo, printHeader (MSGHEADER));
|
||||
#endif
|
||||
puts(printHeader(MSGHEADER));
|
||||
puts(buf);
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
// No attachments? We're done.
|
||||
if (numBPs < 2)
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
|
||||
char *attbuf = NULL;
|
||||
|
||||
printf ("\n");
|
||||
for (i = 1; i < numBPs ; i++)
|
||||
{
|
||||
nextpart = bodyParts [i];
|
||||
|
||||
if (nextpart == NULL)
|
||||
fprintf (stderr, "Error getting part!\n");
|
||||
|
||||
length = 0;
|
||||
type = "";
|
||||
sunDataDescription = "";
|
||||
description = "";
|
||||
name = "";
|
||||
mode = -1;
|
||||
|
||||
nextpart->getContents(env, NULL, &length, &type,
|
||||
&name, &mode, &sunDataDescription);
|
||||
if (handleError (env, "getContents") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
if (type == NULL)
|
||||
type = "(unknown)";
|
||||
|
||||
if (sunDataDescription == NULL)
|
||||
{
|
||||
description = "";
|
||||
} else {
|
||||
// should add bracket or something
|
||||
attbuf = new char [strlen (sunDataDescription) +10];
|
||||
sprintf (attbuf, " (%s)", sunDataDescription);
|
||||
description = attbuf;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
name = "(name)";
|
||||
|
||||
printf ("[%d] \"%s\"%s, ", i, name, description);
|
||||
printf ("%s, %d bytes\n", type, length);
|
||||
|
||||
if (attbuf != NULL)
|
||||
delete [] attbuf;
|
||||
|
||||
}
|
||||
|
||||
delete [] v3_cs;
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
DmxMsg::parse (void)
|
||||
{
|
||||
// store the body parts for later reference
|
||||
|
||||
DtMailEnv env;
|
||||
boolean_t FirstIsText = B_FALSE;
|
||||
DtMail::BodyPart *part = NULL, *nextpart = NULL;
|
||||
char *type = NULL, *attr = NULL;
|
||||
|
||||
int bc = message->getBodyCount (env);
|
||||
if (handleError (env, "getBodyCount") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
part = message->getFirstBodyPart (env);
|
||||
if (handleError (env, "getFirstBodyPart") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
part->getContents (env, NULL, NULL, &type, NULL, NULL, NULL);
|
||||
if (handleError (env, "getContents") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
bodyParts = new (DtMail::BodyPart *[bc]);
|
||||
cachedValues = B_TRUE;
|
||||
|
||||
// cache values
|
||||
bodyParts [0] = part;
|
||||
numBPs++;
|
||||
|
||||
|
||||
if (type != NULL)
|
||||
{
|
||||
attr = DtDtsDataTypeToAttributeValue (type,
|
||||
DtDTS_DA_IS_TEXT,
|
||||
NULL);
|
||||
if (attr != NULL)
|
||||
{
|
||||
FirstIsText = B_TRUE;
|
||||
}
|
||||
//free (type); // it's allocating some data for us
|
||||
} else {
|
||||
FirstIsText = B_FALSE;
|
||||
}
|
||||
|
||||
// No attachments? We're done.
|
||||
if (bc < 2)
|
||||
return;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 1; i < bc; i++)
|
||||
{
|
||||
nextpart = NULL;
|
||||
nextpart = message->getNextBodyPart (env,
|
||||
part);
|
||||
if (handleError (env, "getNextBodyPart") == B_TRUE)
|
||||
exit (1);
|
||||
|
||||
if (nextpart == NULL)
|
||||
fprintf (stderr, "Error getting part!\n");
|
||||
|
||||
|
||||
bodyParts [i] = nextpart;
|
||||
numBPs++;
|
||||
|
||||
part = nextpart;
|
||||
}
|
||||
}
|
||||
|
||||
331
cde/programs/dtmail/dtmailpr/utils.C
Normal file
331
cde/programs/dtmail/dtmailpr/utils.C
Normal file
@@ -0,0 +1,331 @@
|
||||
/* $XConsortium: utils.C /main/4 1996/04/21 19:44:10 drk $ */
|
||||
|
||||
/*
|
||||
*+SNOTICE
|
||||
*
|
||||
* $:$
|
||||
*
|
||||
* RESTRICTED CONFIDENTIAL INFORMATION:
|
||||
*
|
||||
* The information in this document is subject to special
|
||||
* restrictions in a confidential disclosure agreement between
|
||||
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
|
||||
* document outside HP, IBM, Sun, USL, SCO, or Univel without
|
||||
* Sun's specific written approval. This document and all copies
|
||||
* and derivative works thereof must be returned or destroyed at
|
||||
* Sun's request.
|
||||
*
|
||||
* Copyright 1994 Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
*+ENOTICE
|
||||
*/
|
||||
|
||||
#include "dmx.hh"
|
||||
|
||||
// fn proto for mailx fn
|
||||
static char * dispname(const char *hdr);
|
||||
|
||||
// error-handling: should do something with minor codes
|
||||
|
||||
boolean_t
|
||||
handleError (DtMailEnv &dterror, char *msg)
|
||||
{
|
||||
if (dterror.isSet () == DTM_TRUE)
|
||||
{
|
||||
fprintf (stderr, "dtmailpr: (%s) %s\n",
|
||||
msg, (const char *)dterror);
|
||||
dterror.logError (DTM_FALSE, "dtmailpr: (%s) %s\n",
|
||||
msg, (const char *)dterror);
|
||||
|
||||
dterror.clear ();
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
dterror.clear ();
|
||||
return B_FALSE;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
errorString (enum DmxHeaders hdr)
|
||||
{
|
||||
switch (hdr)
|
||||
{
|
||||
case DMXFROM:
|
||||
return "(unknown)";
|
||||
case DMXSUBJ:
|
||||
return "(no subject)";
|
||||
case DMXCLENGTH:
|
||||
return "0";
|
||||
case DMXSTATUS:
|
||||
return " ";
|
||||
case DMXDATE:
|
||||
return "(unknown date)";
|
||||
case DMXTO:
|
||||
return " ";
|
||||
case DMXNUMHDRS:
|
||||
default:
|
||||
return " ";
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
formatHeader (DtMailHeaderLine &info, enum DmxHeaderType htype)
|
||||
{
|
||||
int i = 0, length = 0;
|
||||
int buflength = 0;
|
||||
char *fbuf;
|
||||
|
||||
const char *header [DMXNUMHDRS];
|
||||
|
||||
for (i = 0; i < DMXNUMHDRS; i++)
|
||||
{
|
||||
length = info.header_values[i].length ();
|
||||
if (length == 0)
|
||||
{
|
||||
header [i] = errorString ((enum DmxHeaders)i);
|
||||
} else {
|
||||
header [i] = *((info.header_values[i])[0]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < DMXNUMHDRS; i++)
|
||||
{
|
||||
buflength += strlen (header [i]);
|
||||
}
|
||||
|
||||
fbuf = new char [buflength + 64];
|
||||
|
||||
switch (htype)
|
||||
{
|
||||
case MSGLIST:
|
||||
sprintf (fbuf,
|
||||
"%-18.18s %-16.16s %4ld/%-5s %-.25s",
|
||||
dispname (header [DMXFROM]),
|
||||
header [DMXDATE],
|
||||
atoi (header [DMXCLENGTH]) / 40,
|
||||
header [DMXCLENGTH],
|
||||
header [DMXSUBJ]
|
||||
);
|
||||
break;
|
||||
case MSGHEADER:
|
||||
sprintf (fbuf,
|
||||
"From: %s\nDate: %s\nTo: %s\nSubject: %s\n",
|
||||
dispname (header [DMXFROM]),
|
||||
header [DMXDATE],
|
||||
header [DMXTO],
|
||||
header [DMXSUBJ]);
|
||||
break;
|
||||
case NUMHDRTYPES:
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
return (fbuf); //need to free this after using it
|
||||
}
|
||||
|
||||
// stuff grabbed from mailx...it's ugly, but it looks pretty
|
||||
|
||||
#define NOSTR ((char *) 0) /* Nill string pointer */
|
||||
#define LINESIZE 5120 /* max readable line width */
|
||||
static char *phrase(char *, int , int );
|
||||
|
||||
/*
|
||||
* Return a pointer to a dynamic copy of the argument.
|
||||
*/
|
||||
// changed salloc to malloc
|
||||
char *
|
||||
savestr(char *str)
|
||||
{
|
||||
register char *cp, *cp2, *top;
|
||||
|
||||
for (cp = str; *cp; cp++)
|
||||
;
|
||||
top = (char *)malloc((unsigned)(cp-str + 1));
|
||||
if (top == NOSTR)
|
||||
return(NOSTR);
|
||||
for (cp = str, cp2 = top; *cp; cp++)
|
||||
*cp2++ = *cp;
|
||||
*cp2 = 0;
|
||||
return(top);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
skin(char *name)
|
||||
{
|
||||
return phrase(name, 0, 0);
|
||||
}
|
||||
/*
|
||||
* Return the full name from an RFC-822 header line
|
||||
* or the last two (or one) component of the address.
|
||||
*/
|
||||
|
||||
static char *
|
||||
dispname(const char *hdr)
|
||||
// made it a const char * instead of a char *
|
||||
{
|
||||
char *cp, *cp2;
|
||||
|
||||
if (hdr == 0)
|
||||
return 0;
|
||||
if (((cp = strchr(hdr, '<')) != 0) && (cp > hdr)) {
|
||||
*cp = 0;
|
||||
if ((*hdr == '"') && ((cp = strrchr(++hdr, '"')) != 0))
|
||||
*cp = 0;
|
||||
return (char *)hdr;
|
||||
} else if ((cp = strchr(hdr, '(')) != 0) {
|
||||
hdr = ++cp;
|
||||
if ((cp = strchr(hdr, '+')) != 0)
|
||||
*cp = 0;
|
||||
if ((cp = strrchr(hdr, ')')) != 0)
|
||||
*cp = 0;
|
||||
return (char *)hdr;
|
||||
}
|
||||
cp = skin((char *)hdr);
|
||||
if ((cp2 = strrchr(cp, '!')) != 0) {
|
||||
while (cp2 >= cp && *--cp2 != '!');
|
||||
cp = ++cp2;
|
||||
}
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
||||
#define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */
|
||||
|
||||
/*
|
||||
* Skin an arpa net address according to the RFC 822 interpretation
|
||||
* of "host-phrase."
|
||||
*/
|
||||
// changed salloc to malloc
|
||||
static char *
|
||||
phrase(char *name, int token, int comma)
|
||||
{
|
||||
register char c;
|
||||
register char *cp, *cp2;
|
||||
char *bufend, *nbufp;
|
||||
int gotlt, lastsp, didq;
|
||||
char nbuf[LINESIZE];
|
||||
int nesting;
|
||||
|
||||
if (name == NOSTR)
|
||||
return(NOSTR);
|
||||
if (strlen(name) >= (unsigned)LINESIZE)
|
||||
nbufp = (char *)malloc(strlen(name));
|
||||
else
|
||||
nbufp = nbuf;
|
||||
gotlt = 0;
|
||||
lastsp = 0;
|
||||
bufend = nbufp;
|
||||
for (cp = name, cp2 = bufend; (c = *cp++) != 0;) {
|
||||
switch (c) {
|
||||
case '(':
|
||||
/*
|
||||
Start of a comment, ignore it.
|
||||
*/
|
||||
nesting = 1;
|
||||
while ((c = *cp) != 0) {
|
||||
cp++;
|
||||
switch(c) {
|
||||
case '\\':
|
||||
if (*cp == 0) goto outcm;
|
||||
cp++;
|
||||
break;
|
||||
case '(':
|
||||
nesting++;
|
||||
break;
|
||||
case ')':
|
||||
--nesting;
|
||||
break;
|
||||
}
|
||||
if (nesting <= 0) break;
|
||||
}
|
||||
outcm:
|
||||
lastsp = 0;
|
||||
break;
|
||||
case '"':
|
||||
/*
|
||||
Start a quoted string.
|
||||
Copy it in its entirety.
|
||||
*/
|
||||
didq = 0;
|
||||
while ((c = *cp) != 0) {
|
||||
cp++;
|
||||
switch (c) {
|
||||
case '\\':
|
||||
if ((c = *cp) == 0) goto outqs;
|
||||
cp++;
|
||||
break;
|
||||
case '"':
|
||||
goto outqs;
|
||||
}
|
||||
if (gotlt == 0 || gotlt == '<') {
|
||||
if (lastsp) {
|
||||
lastsp = 0;
|
||||
*cp2++ = ' ';
|
||||
}
|
||||
if (!didq) {
|
||||
*cp2++ = '"';
|
||||
didq++;
|
||||
}
|
||||
*cp2++ = c;
|
||||
}
|
||||
}
|
||||
outqs:
|
||||
if (didq)
|
||||
*cp2++ = '"';
|
||||
lastsp = 0;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
if (token && (!comma || c == '\n')) {
|
||||
done:
|
||||
cp[-1] = 0;
|
||||
return cp;
|
||||
}
|
||||
lastsp = 1;
|
||||
break;
|
||||
|
||||
case ',':
|
||||
*cp2++ = c;
|
||||
if (gotlt != '<') {
|
||||
if (token)
|
||||
goto done;
|
||||
bufend = cp2 + 1;
|
||||
gotlt = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '<':
|
||||
cp2 = bufend;
|
||||
gotlt = c;
|
||||
lastsp = 0;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if (gotlt == '<') {
|
||||
gotlt = c;
|
||||
break;
|
||||
}
|
||||
|
||||
/* FALLTHROUGH . . . */
|
||||
|
||||
default:
|
||||
if (gotlt == 0 || gotlt == '<') {
|
||||
if (lastsp) {
|
||||
lastsp = 0;
|
||||
*cp2++ = ' ';
|
||||
}
|
||||
*cp2++ = c;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*cp2 = 0;
|
||||
return (token ? --cp : equal(name, nbufp) ? name :
|
||||
nbufp == nbuf ? savestr(nbuf) : nbufp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user