1 /* 2 * Heirloom mailx - a mail user agent derived from Berkeley Mail. 3 * 4 * Copyright (c) 2000-2004 Gunnar Ritter, Freiburg i. Br., Germany. 5 */ 6 /* 7 * Copyright (c) 1980, 1993 8 * The Regents of the University of California. All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the University of 21 * California, Berkeley and its contributors. 22 * 4. Neither the name of the University nor the names of its contributors 23 * may be used to endorse or promote products derived from this software 24 * without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * Sccsid @(#)def.h 2.104 (gritter) 3/4/06 39 */ 40 41 /* 42 * Mail -- a mail program 43 * 44 * Author: Kurt Shoens (UCB) March 25, 1978 45 */ 46 47 #if !defined (NI_MAXHOST) || (NI_MAXHOST) < 1025 48 #undef NI_MAXHOST 49 #define NI_MAXHOST 1025 50 #endif 51 52 #define APPEND /* New mail goes to end of mailbox */ 53 54 #define ESCAPE '~' /* Default escape for sending */ 55 #ifndef MAXPATHLEN 56 #ifdef PATH_MAX 57 #define MAXPATHLEN PATH_MAX 58 #else 59 #define MAXPATHLEN 1024 60 #endif 61 #endif 62 #ifndef PATHSIZE 63 #define PATHSIZE MAXPATHLEN /* Size of pathnames throughout */ 64 #endif 65 #define HSHSIZE 59 /* Hash size for aliases and vars */ 66 #define LINESIZE 2560 /* max readable line width */ 67 #define STRINGSIZE ((unsigned) 128)/* Dynamic allocation units */ 68 #define MAXARGC 1024 /* Maximum list of raw strings */ 69 #define MAXEXP 25 /* Maximum expansion of aliases */ 70 71 #define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */ 72 73 #ifdef HAVE_CATGETS 74 #define CATSET 1 75 #else /* !HAVE_CATGETS */ 76 #define catgets(a, b, c, d) (d) 77 #endif /* !HAVE_CATGETS */ 78 79 typedef void (*sighandler_type)(int); 80 81 enum okay { 82 STOP = 0, 83 OKAY = 1 84 }; 85 86 enum mimeenc { 87 MIME_NONE, /* message is not in MIME format */ 88 MIME_BIN, /* message is in binary encoding */ 89 MIME_8B, /* message is in 8bit encoding */ 90 MIME_7B, /* message is in 7bit encoding */ 91 MIME_QP, /* message is quoted-printable */ 92 MIME_B64 /* message is in base64 encoding */ 93 }; 94 95 enum conversion { 96 CONV_NONE, /* no conversion */ 97 CONV_7BIT, /* no conversion, is 7bit */ 98 CONV_FROMQP, /* convert from quoted-printable */ 99 CONV_TOQP, /* convert to quoted-printable */ 100 CONV_8BIT, /* convert to 8bit (iconv) */ 101 CONV_FROMB64, /* convert from base64 */ 102 CONV_FROMB64_T, /* convert from base64/text */ 103 CONV_TOB64, /* convert to base64 */ 104 CONV_FROMHDR, /* convert from RFC1522 format */ 105 CONV_TOHDR, /* convert to RFC1522 format */ 106 CONV_TOHDR_A /* convert addresses for header */ 107 }; 108 109 enum sendaction { 110 SEND_MBOX, /* no conversion to perform */ 111 SEND_RFC822, /* no conversion, no From_ line */ 112 SEND_TODISP, /* convert to displayable form */ 113 SEND_TODISP_ALL, /* same, include all MIME parts */ 114 SEND_SHOW, /* convert to 'show' command form */ 115 SEND_TOSRCH, /* convert for IMAP SEARCH */ 116 SEND_TOFLTR, /* convert for junk mail filtering */ 117 SEND_TOFILE, /* convert for saving body to a file */ 118 SEND_TOPIPE, /* convert for pipe-content/subc. */ 119 SEND_QUOTE, /* convert for quoting */ 120 SEND_QUOTE_ALL, /* same, include all MIME parts */ 121 SEND_DECRYPT /* decrypt */ 122 }; 123 124 enum mimecontent { 125 MIME_UNKNOWN, /* unknown content */ 126 MIME_SUBHDR, /* inside a multipart subheader */ 127 MIME_822, /* message/rfc822 content */ 128 MIME_MESSAGE, /* other message/ content */ 129 MIME_TEXT_PLAIN, /* text/plain content */ 130 MIME_TEXT_HTML, /* text/html content */ 131 MIME_TEXT, /* other text/ content */ 132 MIME_ALTERNATIVE, /* multipart/alternative content */ 133 MIME_DIGEST, /* multipart/digest content */ 134 MIME_MULTI, /* other multipart/ content */ 135 MIME_PKCS7, /* PKCS7 content */ 136 MIME_DISCARD /* content is discarded */ 137 }; 138 139 enum mimeclean { 140 MIME_CLEAN = 000, /* plain RFC 2822 message */ 141 MIME_HIGHBIT = 001, /* characters >= 0200 */ 142 MIME_LONGLINES = 002, /* has lines too long for RFC 2822 */ 143 MIME_CTRLCHAR = 004, /* contains control characters */ 144 MIME_HASNUL = 010, /* contains \0 characters */ 145 MIME_NOTERMNL = 020 /* lacks a terminating newline */ 146 }; 147 148 enum tdflags { 149 TD_NONE = 0, /* no display conversion */ 150 TD_ISPR = 01, /* use isprint() checks */ 151 TD_ICONV = 02, /* use iconv() */ 152 TD_DELCTRL = 04 /* delete control characters */ 153 }; 154 155 struct str { 156 char *s; /* the string's content */ 157 size_t l; /* the stings's length */ 158 }; 159 160 enum protocol { 161 PROTO_FILE, /* refers to a local file */ 162 PROTO_POP3, /* is a pop3 server string */ 163 PROTO_IMAP, /* is an imap server string */ 164 PROTO_MAILDIR, /* refers to a maildir folder */ 165 PROTO_UNKNOWN /* unknown protocol */ 166 }; 167 168 struct sock { /* data associated with a socket */ 169 int s_fd; /* file descriptor */ 170 #ifdef USE_SSL 171 int s_use_ssl; /* SSL is used */ 172 #if defined (USE_NSS) 173 void *s_prfd; /* NSPR file descriptor */ 174 #elif defined (USE_OPENSSL) 175 void *s_ssl; /* SSL object */ 176 void *s_ctx; /* SSL context object */ 177 #endif /* SSL library specific */ 178 #endif /* USE_SSL */ 179 char *s_wbuf; /* for buffered writes */ 180 int s_wbufsize; /* allocated size of s_buf */ 181 int s_wbufpos; /* position of first empty data byte */ 182 char s_rbuf[LINESIZE+1]; /* for buffered reads */ 183 char *s_rbufptr; /* read pointer to s_rbuf */ 184 int s_rsz; /* size of last read in s_rbuf */ 185 char *s_desc; /* description of error messages */ 186 void (*s_onclose)(void); /* execute on close */ 187 }; 188 189 struct mailbox { 190 struct sock mb_sock; /* socket structure */ 191 enum { 192 MB_NONE = 000, /* no reply expected */ 193 MB_COMD = 001, /* command reply expected */ 194 MB_MULT = 002, /* multiline reply expected */ 195 MB_PREAUTH = 004, /* not in authenticated state */ 196 MB_BYE = 010 /* may accept a BYE state */ 197 } mb_active; 198 FILE *mb_itf; /* temp file with messages, read open */ 199 FILE *mb_otf; /* same, write open */ 200 char *mb_sorted; /* sort method */ 201 enum { 202 MB_VOID, /* no type (e. g. connection failed) */ 203 MB_FILE, /* local file */ 204 MB_POP3, /* POP3 mailbox */ 205 MB_IMAP, /* IMAP mailbox */ 206 MB_MAILDIR, /* maildir folder */ 207 MB_CACHE /* cached mailbox */ 208 } mb_type; /* type of mailbox */ 209 enum { 210 MB_DELE = 01, /* may delete messages in mailbox */ 211 MB_EDIT = 02 /* may edit messages in mailbox */ 212 } mb_perm; 213 int mb_compressed; /* is a compressed mbox file */ 214 int mb_threaded; /* mailbox has been threaded */ 215 enum mbflags { 216 MB_NOFLAGS = 000, 217 MB_UIDPLUS = 001 /* supports IMAP UIDPLUS */ 218 } mb_flags; 219 unsigned long mb_uidvalidity; /* IMAP unique identifier validity */ 220 char *mb_imap_account; /* name of current IMAP account */ 221 char *mb_imap_mailbox; /* name of current IMAP mailbox */ 222 char *mb_cache_directory; /* name of cache directory */ 223 }; 224 225 enum needspec { 226 NEED_UNSPEC, /* unspecified need, don't fetch */ 227 NEED_HEADER, /* need the header of a message */ 228 NEED_BODY /* need header and body of a message */ 229 }; 230 231 enum havespec { 232 HAVE_NOTHING = 0, /* nothing downloaded yet */ 233 HAVE_HEADER = 01, /* header is downloaded */ 234 HAVE_BODY = 02 /* entire message is downloaded */ 235 }; 236 237 /* 238 * flag bits. Attention: Flags that are used in cache.c may not change. 239 */ 240 enum mflag { 241 MUSED = (1<<0), /* entry is used, but this bit isn't */ 242 MDELETED = (1<<1), /* entry has been deleted */ 243 MSAVED = (1<<2), /* entry has been saved */ 244 MTOUCH = (1<<3), /* entry has been noticed */ 245 MPRESERVE = (1<<4), /* keep entry in sys mailbox */ 246 MMARK = (1<<5), /* message is marked! */ 247 MODIFY = (1<<6), /* message has been modified */ 248 MNEW = (1<<7), /* message has never been seen */ 249 MREAD = (1<<8), /* message has been read sometime. */ 250 MSTATUS = (1<<9), /* message status has changed */ 251 MBOX = (1<<10), /* Send this to mbox, regardless */ 252 MNOFROM = (1<<11), /* no From line */ 253 MHIDDEN = (1<<12), /* message is hidden to user */ 254 MFULLYCACHED = (1<<13), /* message is completely cached */ 255 MBOXED = (1<<14), /* message has been sent to mbox */ 256 MUNLINKED = (1<<15), /* message was unlinked from cache */ 257 MNEWEST = (1<<16), /* message is very new (newmail) */ 258 MFLAG = (1<<17), /* message has been flagged recently */ 259 MUNFLAG = (1<<18), /* message has been unflagged */ 260 MFLAGGED = (1<<19), /* message is `flagged' */ 261 MANSWER = (1<<20), /* message has been answered recently */ 262 MUNANSWER = (1<<21), /* message has been unanswered */ 263 MANSWERED = (1<<22), /* message is `answered' */ 264 MDRAFT = (1<<23), /* message has been drafted recently */ 265 MUNDRAFT = (1<<24), /* message has been undrafted */ 266 MDRAFTED = (1<<25), /* message is marked as `draft' */ 267 MKILL = (1<<26), /* message has been killed */ 268 MOLDMARK = (1<<27), /* messages was marked previously */ 269 MJUNK = (1<<28) /* message is classified as junk */ 270 }; 271 272 struct mimepart { 273 enum mflag m_flag; /* flags */ 274 enum havespec m_have; /* downloaded parts of the part */ 275 int m_block; /* block number of this part */ 276 size_t m_offset; /* offset in block of part */ 277 size_t m_size; /* Bytes in the part */ 278 size_t m_xsize; /* Bytes in the full part */ 279 long m_lines; /* Lines in the message */ 280 long m_xlines; /* Lines in the full message */ 281 time_t m_time; /* time the message was sent */ 282 char *m_from; /* message sender */ 283 struct mimepart *m_nextpart; /* next part at same level */ 284 struct mimepart *m_multipart; /* parts of multipart */ 285 struct mimepart *m_parent; /* enclosing multipart part */ 286 char *m_ct_type; /* content-type */ 287 char *m_ct_type_plain; /* content-type without specs */ 288 enum mimecontent m_mimecontent; /* same in enum */ 289 char *m_charset; /* charset */ 290 char *m_ct_transfer_enc; /* content-transfer-encoding */ 291 enum mimeenc m_mimeenc; /* same in enum */ 292 char *m_partstring; /* part level string */ 293 char *m_filename; /* attachment filename */ 294 }; 295 296 struct message { 297 enum mflag m_flag; /* flags */ 298 enum havespec m_have; /* downloaded parts of the message */ 299 int m_block; /* block number of this message */ 300 size_t m_offset; /* offset in block of message */ 301 size_t m_size; /* Bytes in the message */ 302 size_t m_xsize; /* Bytes in the full message */ 303 long m_lines; /* Lines in the message */ 304 long m_xlines; /* Lines in the full message */ 305 time_t m_time; /* time the message was sent */ 306 time_t m_date; /* time in the 'Date' field */ 307 unsigned m_idhash; /* hash on Message-ID for threads */ 308 unsigned long m_uid; /* IMAP unique identifier */ 309 struct message *m_child; /* first child of this message */ 310 struct message *m_younger; /* younger brother of this message */ 311 struct message *m_elder; /* elder brother of this message */ 312 struct message *m_parent; /* parent of this message */ 313 unsigned m_level; /* thread level of message */ 314 long m_threadpos; /* position in threaded display */ 315 float m_score; /* score of message */ 316 char *m_maildir_file; /* original maildir file of msg */ 317 unsigned m_maildir_hash; /* hash of file name in maildir sub */ 318 int m_collapsed; /* collapsed thread information */ 319 }; 320 321 /* 322 * Given a file address, determine the block number it represents. 323 */ 324 #define mailx_blockof(off) ((int) ((off) / 4096)) 325 #define mailx_offsetof(off) ((int) ((off) % 4096)) 326 #define mailx_positionof(block, offset) ((off_t)(block) * 4096 + (offset)) 327 328 /* 329 * Argument types. 330 */ 331 enum argtype { 332 MSGLIST = 0, /* Message list type */ 333 STRLIST = 1, /* A pure string */ 334 RAWLIST = 2, /* Shell string list */ 335 NOLIST = 3, /* Just plain 0 */ 336 NDMLIST = 4, /* Message list, no defaults */ 337 ECHOLIST= 5, /* Like raw list, but keep quote chars */ 338 P = 040, /* Autoprint dot after command */ 339 I = 0100, /* Interactive command bit */ 340 M = 0200, /* Legal from send mode bit */ 341 W = 0400, /* Illegal when read only bit */ 342 F = 01000, /* Is a conditional command */ 343 T = 02000, /* Is a transparent command */ 344 R = 04000, /* Cannot be called from collect */ 345 A = 010000 /* Needs an active mailbox */ 346 }; 347 348 /* 349 * Oft-used mask values 350 */ 351 352 #define MMNORM (MDELETED|MSAVED|MHIDDEN)/* Look at both save and delete bits */ 353 #define MMNDEL (MDELETED|MHIDDEN) /* Look only at deleted bit */ 354 355 /* 356 * Format of the command description table. 357 * The actual table is declared and initialized 358 * in lex.c 359 */ 360 struct cmd { 361 char *c_name; /* Name of command */ 362 int (*c_func)(void *); /* Implementor of the command */ 363 enum argtype c_argtype; /* Type of arglist (see below) */ 364 short c_msgflag; /* Required flags of messages */ 365 short c_msgmask; /* Relevant flags of messages */ 366 }; 367 368 /* Yechh, can't initialize unions */ 369 370 #define c_minargs c_msgflag /* Minimum argcount for RAWLIST */ 371 #define c_maxargs c_msgmask /* Max argcount for RAWLIST */ 372 373 /* 374 * Structure used to return a break down of a head 375 * line (hats off to Bill Joy!) 376 */ 377 378 struct headline { 379 char *l_from; /* The name of the sender */ 380 char *l_tty; /* His tty string (if any) */ 381 char *l_date; /* The entire date string */ 382 }; 383 384 enum gfield { 385 GTO = 1, /* Grab To: line */ 386 GSUBJECT= 2, /* Likewise, Subject: line */ 387 GCC = 4, /* And the Cc: line */ 388 GBCC = 8, /* And also the Bcc: line */ 389 390 GNL = 16, /* Print blank line after */ 391 GDEL = 32, /* Entity removed from list */ 392 GCOMMA = 64, /* detract puts in commas */ 393 GUA = 128, /* User-Agent field */ 394 GMIME = 256, /* MIME 1.0 fields */ 395 GMSGID = 512, /* a Message-ID */ 396 /* 1024 */ /* unused */ 397 GIDENT = 2048, /* From:, Reply-To: and Organization: field */ 398 GREF = 4096, /* References: field */ 399 GDATE = 8192, /* Date: field */ 400 GFULL = 16384, /* include full names */ 401 GSKIN = 32768, /* skin names */ 402 GEXTRA = 65536, /* extra fields */ 403 GFILES = 131072 /* include filename addresses */ 404 }; 405 406 #define GMASK (GTO|GSUBJECT|GCC|GBCC) /* Mask of places from whence */ 407 408 #define visible(mp) (((mp)->m_flag&(MDELETED|MHIDDEN|MKILL))==0|| \ 409 dot==(mp) && (mp)->m_flag&MKILL) 410 411 /* 412 * Structure used to pass about the current 413 * state of the user-typed message header. 414 */ 415 416 struct header { 417 struct name *h_to; /* Dynamic "To:" string */ 418 char *h_subject; /* Subject string */ 419 struct name *h_cc; /* Carbon copies string */ 420 struct name *h_bcc; /* Blind carbon copies */ 421 struct name *h_ref; /* References */ 422 struct name *h_smopts; /* Sendmail options */ 423 struct attachment *h_attach; /* MIME attachments */ 424 char *h_charset; /* preferred charset */ 425 struct name *h_from; /* overridden "From:" field */ 426 struct name *h_replyto; /* overridden "Reply-To:" field */ 427 struct name *h_sender; /* overridden "Sender:" field */ 428 char *h_organization; /* overridden "Organization:" field */ 429 }; 430 431 /* 432 * Structure of namelist nodes used in processing 433 * the recipients of mail and aliases and all that 434 * kind of stuff. 435 */ 436 437 struct name { 438 struct name *n_flink; /* Forward link in list. */ 439 struct name *n_blink; /* Backward list link */ 440 enum gfield n_type; /* From which list it came */ 441 char *n_name; /* This fella's name */ 442 char *n_fullname; /* Sometimes, name including comment */ 443 }; 444 445 /* 446 * Structure of a MIME attachment. 447 */ 448 449 struct attachment { 450 struct attachment *a_flink; /* Forward link in list. */ 451 struct attachment *a_blink; /* Backward list link */ 452 char *a_name; /* file name */ 453 char *a_content_type; /* content type */ 454 char *a_content_disposition; /* content disposition */ 455 char *a_content_id; /* content id */ 456 char *a_content_description; /* content description */ 457 char *a_charset; /* character set */ 458 int a_msgno; /* message number */ 459 }; 460 461 /* 462 * Structure of a variable node. All variables are 463 * kept on a singly-linked list of these, rooted by 464 * "variables" 465 */ 466 467 struct var { 468 struct var *v_link; /* Forward link to next variable */ 469 char *v_name; /* The variable's name */ 470 char *v_value; /* And it's current value */ 471 }; 472 473 struct group { 474 struct group *ge_link; /* Next person in this group */ 475 char *ge_name; /* This person's user name */ 476 }; 477 478 struct grouphead { 479 struct grouphead *g_link; /* Next grouphead in list */ 480 char *g_name; /* Name of this group */ 481 struct group *g_list; /* Users in group. */ 482 }; 483 484 /* 485 * Structure of the hash table of ignored header fields 486 */ 487 struct ignoretab { 488 int i_count; /* Number of entries */ 489 struct ignore { 490 struct ignore *i_link; /* Next ignored field in bucket */ 491 char *i_field; /* This ignored field */ 492 } *i_head[HSHSIZE]; 493 }; 494 495 /* 496 * Token values returned by the scanner used for argument lists. 497 * Also, sizes of scanner-related things. 498 */ 499 enum ltoken { 500 TEOL = 0, /* End of the command line */ 501 TNUMBER = 1, /* A message number */ 502 TDASH = 2, /* A simple dash */ 503 TSTRING = 3, /* A string (possibly containing -) */ 504 TDOT = 4, /* A "." */ 505 TUP = 5, /* An "^" */ 506 TDOLLAR = 6, /* A "$" */ 507 TSTAR = 7, /* A "*" */ 508 TOPEN = 8, /* An '(' */ 509 TCLOSE = 9, /* A ')' */ 510 TPLUS = 10, /* A '+' */ 511 TERROR = 11, /* A lexical error */ 512 TCOMMA = 12, /* A ',' */ 513 TSEMI = 13, /* A ';' */ 514 TBACK = 14 /* A '`' */ 515 }; 516 517 #define REGDEP 2 /* Maximum regret depth. */ 518 519 /* 520 * Constants for conditional commands. These describe whether 521 * we should be executing stuff or not. 522 */ 523 enum condition { 524 CANY = 0, /* Execute in send or receive mode */ 525 CRCV = 1, /* Execute in receive mode only */ 526 CSEND = 2, /* Execute in send mode only */ 527 CTERM = 3, /* Execute only if stdin is a tty */ 528 CNONTERM= 4 /* Execute only if stdin not tty */ 529 }; 530 531 /* 532 * For the 'shortcut' and 'unshortcut' functionality. 533 */ 534 struct shortcut { 535 struct shortcut *sh_next; /* next shortcut in list */ 536 char *sh_short; /* shortcut string */ 537 char *sh_long; /* expanded form */ 538 }; 539 540 /* 541 * Kludges to handle the change from setexit / reset to setjmp / longjmp 542 */ 543 544 #define setexit() sigsetjmp(srbuf, 1) 545 #define reset(x) siglongjmp(srbuf, x) 546 547 /* 548 * Locale-independent character classes. 549 */ 550 enum { 551 C_CNTRL = 0000, 552 C_BLANK = 0001, 553 C_WHITE = 0002, 554 C_SPACE = 0004, 555 C_PUNCT = 0010, 556 C_OCTAL = 0020, 557 C_DIGIT = 0040, 558 C_UPPER = 0100, 559 C_LOWER = 0200 560 }; 561 562 extern const unsigned char class_char[]; 563 564 #define asciichar(c) ((unsigned)(c) <= 0177) 565 #define alnumchar(c) (asciichar(c)&&(class_char[c]&\ 566 (C_DIGIT|C_OCTAL|C_UPPER|C_LOWER))) 567 #define alphachar(c) (asciichar(c)&&(class_char[c]&(C_UPPER|C_LOWER))) 568 #define blankchar(c) (asciichar(c)&&(class_char[c]&(C_BLANK))) 569 #define cntrlchar(c) (asciichar(c)&&(class_char[c]==C_CNTRL)) 570 #define digitchar(c) (asciichar(c)&&(class_char[c]&(C_DIGIT|C_OCTAL))) 571 #define lowerchar(c) (asciichar(c)&&(class_char[c]&(C_LOWER))) 572 #define punctchar(c) (asciichar(c)&&(class_char[c]&(C_PUNCT))) 573 #define spacechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_SPACE|C_WHITE))) 574 #define upperchar(c) (asciichar(c)&&(class_char[c]&(C_UPPER))) 575 #define whitechar(c) (asciichar(c)&&(class_char[c]&(C_BLANK|C_WHITE))) 576 #define octalchar(c) (asciichar(c)&&(class_char[c]&(C_OCTAL))) 577 578 #define upperconv(c) (lowerchar(c) ? (c)-'a'+'A' : (c)) 579 #define lowerconv(c) (upperchar(c) ? (c)-'A'+'a' : (c)) 580 /* RFC 822, 3.2. */ 581 #define fieldnamechar(c) (asciichar(c)&&(c)>040&&(c)!=0177&&(c)!=':') 582 583 /* 584 * Truncate a file to the last character written. This is 585 * useful just before closing an old file that was opened 586 * for read/write. 587 */ 588 #define trunc(stream) { \ 589 fflush(stream); \ 590 ftruncate(fileno(stream), (off_t)ftell(stream)); \ 591 } 592 593 /* 594 * Use either alloca() or smalloc()/free(). ac_alloc can be used to 595 * allocate space within a function. ac_free must be called when the 596 * space is no longer needed, but expands to nothing if using alloca(). 597 */ 598 #ifdef HAVE_ALLOCA 599 #define ac_alloc(n) alloca(n) 600 #define ac_free(n) 601 #else /* !HAVE_ALLOCA */ 602 #define ac_alloc(n) smalloc(n) 603 #define ac_free(n) free(n) 604 #endif /* !HAVE_ALLOCA */ 605 606 /* 607 * glibc uses the slow thread-safe getc() even if _REENTRANT is not 608 * defined. Work around it. 609 */ 610 #ifdef __GLIBC__ 611 #undef getc 612 #define getc(c) getc_unlocked(c) 613 #undef putc 614 #define putc(c, f) putc_unlocked(c, f) 615 #undef putchar 616 #define putchar(c) putc_unlocked((c), stdout) 617 #endif /* __GLIBC__ */ 618 619 #define CBAD (-15555) 620 621 #define smin(a, b) ((a) < (b) ? (a) : (b)) 622 #define smax(a, b) ((a) < (b) ? (b) : (a)) 623 624 /* 625 * For saving the current directory and later returning. 626 */ 627 #ifdef HAVE_FCHDIR 628 struct cw { 629 int cw_fd; 630 }; 631 #else /* !HAVE_FCHDIR */ 632 struct cw { 633 char cw_wd[PATHSIZE]; 634 }; 635 #endif /* !HAVE_FCHDIR */ 636 637 #ifdef USE_SSL 638 enum ssl_vrfy_level { 639 VRFY_IGNORE, 640 VRFY_WARN, 641 VRFY_ASK, 642 VRFY_STRICT 643 }; 644 #endif /* USE_SSL */ 645