1 /* $NetBSD: def.h,v 1.29 2026/06/25 22:27:52 kre Exp $ */ 2 /* 3 * Copyright (c) 1980, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * @(#)def.h 8.4 (Berkeley) 4/20/95 31 * $NetBSD: def.h,v 1.29 2026/06/25 22:27:52 kre Exp $ 32 */ 33 34 /* 35 * Mail -- a mail program 36 * 37 * Author: Kurt Shoens (UCB) March 25, 1978 38 */ 39 40 #ifndef __DEF_H__ 41 #define __DEF_H__ 42 43 #include <sys/types.h> 44 #include <sys/file.h> 45 #include <sys/ioctl.h> 46 #include <sys/stat.h> 47 #include <sys/param.h> 48 #include <sys/time.h> 49 #include <sys/wait.h> 50 51 #include <ctype.h> 52 #include <err.h> 53 #include <errno.h> 54 #include <fcntl.h> 55 #include <paths.h> 56 #include <pwd.h> 57 #include <setjmp.h> 58 #include <signal.h> 59 #include <stdio.h> 60 #include <stdlib.h> 61 #include <string.h> 62 #include <termios.h> 63 #include <time.h> 64 #include <unistd.h> 65 #include <vis.h> 66 67 #include "pathnames.h" 68 69 #define APPEND /* New mail goes to end of mailbox */ 70 71 #define COMMENT_CHAR '#' /* Comment character when sourcing */ 72 #define ESCAPE '~' /* Default escape for sending */ 73 #define NMLSIZE 1024 /* max names in a message list */ 74 #define PATHSIZE MAXPATHLEN /* Size of pathnames throughout */ 75 #define HSHSIZE 59 /* Hash size for aliases and vars */ 76 #define LINESIZE BUFSIZ /* max readable line width */ 77 #define MAXARGC 1024 /* Maximum list of raw strings */ 78 #define MAXEXP 25 /* Maximum expansion of aliases */ 79 80 #define PUBLIC /* make it easy to find the entry points */ 81 82 /* 83 * User environment variable names. 84 * See complete.h, mime.h, and thread.h for names specific to those modules. 85 */ 86 #define ENAME_INDENT_POSTSCRIPT "indentpostscript" 87 #define ENAME_INDENT_PREAMBLE "indentpreamble" 88 #define ENAME_APPEND "append" 89 #define ENAME_ASK "ask" 90 #define ENAME_ASKBCC "askbcc" 91 #define ENAME_ASKCC "askcc" 92 #define ENAME_ASKSUB "asksub" 93 #define ENAME_AUTOINC "autoinc" 94 #define ENAME_AUTOPRINT "autoprint" 95 #define ENAME_CRT "crt" 96 #define ENAME_DEAD "DEAD" 97 #define ENAME_DEBUG "debug" 98 #define ENAME_DONTSENDEMPTY "dontsendempty" 99 #define ENAME_DOT "dot" 100 #define ENAME_EDITOR "EDITOR" 101 #define ENAME_ENABLE_PIPES "enable-pipes" 102 #define ENAME_ESCAPE "escape" 103 #define ENAME_FOLDER "folder" 104 #define ENAME_HEADER_FORMAT "header-format" 105 #define ENAME_HOLD "hold" 106 #define ENAME_IGNORE "ignore" 107 #define ENAME_IGNOREEOF "ignoreeof" 108 #define ENAME_INDENTPREFIX "indentprefix" 109 #define ENAME_INTERACTIVE "interactive" 110 #define ENAME_KEEP "keep" 111 #define ENAME_KEEPSAVE "keepsave" 112 #define ENAME_LISTER "LISTER" 113 #define ENAME_MBOX "MBOX" 114 #define ENAME_METOO "metoo" 115 #define ENAME_NOHEADER "noheader" 116 #define ENAME_NOSAVE "nosave" 117 #define ENAME_PAGE_ALSO "page-also" 118 #define ENAME_PAGER "PAGER" 119 #define ENAME_PAGER_OFF "pager-off" 120 #define ENAME_PROMPT "prompt" 121 #define ENAME_QUIET "quiet" 122 #define ENAME_RECORD "record" 123 #define ENAME_REGEX_SEARCH "regex-search" 124 #define ENAME_REPLYALL "Replyall" 125 #define ENAME_REPLYASRECIPIENT "ReplyAsRecipient" 126 #define ENAME_SCREEN "screen" 127 #define ENAME_SCREENHEIGHT "screenheight" 128 #define ENAME_SCREENWIDTH "screenwidth" 129 #define ENAME_SEARCHHEADERS "searchheaders" 130 #define ENAME_SENDMAIL "sendmail" 131 #define ENAME_SHELL "SHELL" 132 #define ENAME_SHOW_RCPT "show-rcpt" 133 #define ENAME_SMOPTS_VERIFY "smopts-verify" 134 #define ENAME_TOPLINES "toplines" 135 #define ENAME_VERBOSE "verbose" 136 #define ENAME_VISUAL "VISUAL" 137 138 #define equal(a, b) (strcmp(a,b)==0)/* A nice function to string compare */ 139 140 union msgref { 141 struct message *link; /* the usual content of the field */ 142 ptrdiff_t offset; /* temporary use during turbulence */ 143 }; 144 145 struct message { 146 short m_flag; /* flags, see below */ 147 short m_offset; /* offset in block of message */ 148 long m_block; /* block number of this message */ 149 long m_lines; /* Lines in the message */ 150 off_t m_size; /* Bytes in the message */ 151 long m_blines; /* Body (non-header) lines */ 152 153 /* 154 * threading fields 155 */ 156 int m_index; /* message index in this thread */ 157 int m_depth; /* depth in thread */ 158 union msgref m_f; /* link to next message */ 159 union msgref m_b; /* link to previous message */ 160 union msgref m_c; /* link to child of this message */ 161 union msgref m_p; /* link to parent of thread */ 162 }; 163 typedef struct mime_info mime_info_t; /* phantom structure only to attach.c */ 164 165 #define m_flink m_f.link /* for access to usual members */ 166 #define m_blink m_b.link /* all are struct message * */ 167 #define m_clink m_c.link 168 #define m_plink m_p.link 169 170 /* 171 * flag bits. 172 */ 173 174 #define MUSED (1<<0) /* entry is used, but this bit isn't */ 175 #define MDELETED (1<<1) /* entry has been deleted */ 176 #define MSAVED (1<<2) /* entry has been saved */ 177 #define MTOUCH (1<<3) /* entry has been noticed */ 178 #define MPRESERVE (1<<4) /* keep entry in sys mailbox */ 179 #define MMARK (1<<5) /* message is marked! */ 180 #define MMODIFY (1<<6) /* message has been modified */ 181 #define MNEW (1<<7) /* message has never been seen */ 182 #define MREAD (1<<8) /* message has been read sometime. */ 183 #define MSTATUS (1<<9) /* message status has changed */ 184 #define MBOX (1<<10) /* Send this to mbox, regardless */ 185 #define MTAGGED (1<<11) /* message has been tagged */ 186 187 /* 188 * Given a file address, determine the block number it represents. 189 */ 190 #define blockof(off) ((int) ((off) / 4096)) 191 #define blkoffsetof(off) ((int) ((off) % 4096)) 192 #define positionof(block, offset) ((off_t)(block) * 4096 + (offset)) 193 194 /* 195 * Format of the command description table. 196 * The actual table is declared and initialized 197 * in lex.c 198 */ 199 struct cmd { 200 const char *c_name; /* Name of command */ 201 int (*c_func)(void *); /* Implementor of the command */ 202 int c_pipe; /* Pipe output through the pager */ 203 # define C_PIPE_PAGER 1 /* enable use of pager */ 204 # define C_PIPE_CRT 2 /* use the pager if CRT is defined */ 205 # define C_PIPE_SHELL 4 /* enable shell pipes */ 206 #ifdef USE_EDITLINE 207 const char *c_complete; /* String describing completion */ 208 #endif 209 short c_argtype; /* Type of arglist (see below) */ 210 short c_msgflag; /* Required flags of messages */ 211 short c_msgmask; /* Relevant flags of messages */ 212 }; 213 214 /* Yechh, can't initialize unions */ 215 216 #define c_minargs c_msgflag /* Minimum argcount for RAWLIST */ 217 #define c_maxargs c_msgmask /* Max argcount for RAWLIST */ 218 219 /* 220 * Argument types. 221 */ 222 223 #define MSGLIST 0 /* Message list type */ 224 #define STRLIST 1 /* A pure string */ 225 #define RAWLIST 2 /* Shell string list */ 226 #define NOLIST 3 /* Just plain 0 */ 227 #define NDMLIST 4 /* Message list, no defaults */ 228 229 #define P 0x010 /* Autoprint dot after command */ 230 #define I 0x020 /* Interactive command bit */ 231 #define M 0x040 /* Legal from send mode bit */ 232 #define W 0x080 /* Illegal when read only bit */ 233 #define F 0x100 /* Is a conditional command */ 234 #define T 0x200 /* Is a transparent command */ 235 #define R 0x400 /* Cannot be called from collect */ 236 #define ARGTYPE_MASK ~(P|I|M|W|F|T|R) 237 238 /* 239 * Oft-used mask values 240 */ 241 242 #define MMNORM (MDELETED|MSAVED)/* Look at both save and delete bits */ 243 #define MMNDEL MDELETED /* Look only at deleted bit */ 244 245 /* 246 * Structure used to return a break down of a head 247 * line (hats off to Bill Joy!) 248 */ 249 250 struct headline { 251 char *l_from; /* The name of the sender */ 252 char *l_tty; /* His tty string (if any) */ 253 char *l_date; /* The entire date string */ 254 }; 255 256 #define GTO 0x001 /* Grab To: line */ 257 #define GSUBJECT 0x002 /* Likewise, Subject: line */ 258 #define GCC 0x004 /* And the Cc: line */ 259 #define GBCC 0x008 /* And also the Bcc: line */ 260 #define GSMOPTS 0x010 /* Grab the sendmail options */ 261 #define GMISC 0x020 /* miscellaneous extra fields for sending */ 262 #ifdef MIME_SUPPORT 263 #define GMIME 0x040 /* mime flag */ 264 #endif 265 #define GMASK (GTO | GSUBJECT | GCC | GBCC | GSMOPTS) 266 /* Mask of places from whence */ 267 268 #define GNL 0x100 /* Print blank line after */ 269 #define GDEL 0x200 /* Entity removed from list */ 270 #define GCOMMA 0x400 /* detract puts in commas */ 271 272 #ifdef MIME_SUPPORT 273 /* 274 * Structure of MIME content. 275 */ 276 struct Content { 277 const char *C_type; /* content type */ 278 const char *C_encoding; /* content transfer encoding */ 279 const char *C_disposition; /* content disposition */ 280 const char *C_description; /* content description */ 281 const char *C_id; /* content id */ 282 }; 283 /* Header strings corresponding to the above Content fields. */ 284 #define MIME_HDR_TYPE "Content-Type" 285 #define MIME_HDR_ENCODING "Content-Transfer-Encoding" 286 #define MIME_HDR_DISPOSITION "Content-Disposition" 287 #define MIME_HDR_ID "Content-ID" 288 #define MIME_HDR_DESCRIPTION "Content-Description" 289 #define MIME_HDR_VERSION "MIME-Version" 290 /* the value of the MIME-Version field */ 291 #define MIME_VERSION "1.0" 292 293 typedef enum { 294 ATTACH_INVALID = 0, /* do not use! */ 295 ATTACH_FNAME = 1, 296 ATTACH_MSG = 2, 297 ATTACH_FILENO = 3 298 } attach_t; 299 300 /* 301 * Structure of a MIME attachment. 302 */ 303 struct attachment { 304 struct attachment *a_flink; /* Forward link in list. */ 305 struct attachment *a_blink; /* Backward list link */ 306 307 attach_t a_type; /* attachment type */ 308 #if 1 309 union { 310 char *u_name; /* file name */ 311 struct message *u_msg; /* message */ 312 int u_fileno; /* file number */ 313 } a_u; 314 315 #define a_name a_u.u_name 316 #define a_msg a_u.u_msg 317 #define a_fileno a_u.u_fileno 318 #else 319 char *a_name; /* file name */ 320 struct message *a_msg; /* message */ 321 int a_fileno; /* file number */ 322 #endif 323 324 struct Content a_Content; /* MIME content strings */ 325 }; 326 #endif /* MIME_SUPPORT */ 327 328 /* 329 * Structure used to pass about the current 330 * state of the user-typed message header. 331 */ 332 333 struct header { 334 struct name *h_to; /* Dynamic "To:" string */ 335 char *h_subject; /* Subject string */ 336 struct name *h_cc; /* Carbon copies string */ 337 struct name *h_bcc; /* Blind carbon copies */ 338 struct name *h_smopts; /* Sendmail options */ 339 char *h_in_reply_to; /* In-Reply-To: field */ 340 struct name *h_references; /* References: field */ 341 struct name *h_extra; /* extra header fields */ 342 #ifdef MIME_SUPPORT 343 char *h_mime_boundary; /* MIME multipart boundary string */ 344 struct Content h_Content; /* MIME content for message */ 345 struct attachment *h_attach; /* MIME attachments */ 346 #endif 347 }; 348 349 /* 350 * Structure of namelist nodes used in processing 351 * the recipients of mail and aliases and all that 352 * kind of stuff. 353 */ 354 355 struct name { 356 struct name *n_flink; /* Forward link in list. */ 357 struct name *n_blink; /* Backward list link */ 358 short n_type; /* From which list it came */ 359 char *n_name; /* This fella's name */ 360 }; 361 362 /* 363 * Structure of a variable node. All variables are 364 * kept on a singly-linked list of these, rooted by 365 * "variables" 366 */ 367 368 struct var { 369 struct var *v_link; /* Forward link to next variable */ 370 char *v_name; /* The variable's name */ 371 char *v_value; /* And its current value */ 372 }; 373 374 struct group { 375 struct group *ge_link; /* Next person in this group */ 376 char *ge_name; /* This person's user name */ 377 }; 378 379 struct grouphead { 380 struct grouphead *g_link; /* Next grouphead in list */ 381 char *g_name; /* Name of this group */ 382 struct group *g_list; /* Users in group. */ 383 }; 384 385 struct smopts_s { 386 struct smopts_s *s_link; /* Link to next smopts_s in list */ 387 char *s_name; /* Name of this smopts_s */ 388 struct name *s_smopts; /* sendmail options name list */ 389 }; 390 391 /* 392 * Structure of the hash table of ignored header fields 393 */ 394 struct ignoretab { 395 size_t i_count; /* Number of entries */ 396 struct ignore { 397 struct ignore *i_link; /* Next ignored field in bucket */ 398 char *i_field; /* This ignored field */ 399 } *i_head[HSHSIZE]; 400 }; 401 402 /* 403 * Constants for conditional commands. These control whether we 404 * should be executing commands or not. 405 */ 406 struct cond_stack_s { 407 struct cond_stack_s *c_next; 408 int c_cond; 409 }; 410 #define CNONE 0x00 /* Execute everything */ 411 #define CSKIP 0x01 /* Do not execute commands */ 412 #define CIF 0x02 /* Inside if/endif block */ 413 #define CELSE 0x04 /* The last conditional was else */ 414 #define CIGN 0x08 /* Conditional in a skipped block */ 415 416 enum mailmode_e { 417 mm_receiving, /* receiving mail mode */ 418 mm_sending, /* sending mail mode */ 419 mm_hdrsonly /* headers only mode */ 420 }; 421 422 /* 423 * Truncate a file to the last character written. This is 424 * useful just before closing an old file that was opened 425 * for read/write. 426 */ 427 #define trunc(stream) { \ 428 (void)fflush(stream); \ 429 (void)ftruncate(fileno(stream), (off_t)ftell(stream)); \ 430 } 431 432 /* 433 * White Space (WSP) as specified in see RFC 2822. 434 * 435 * NOTE: Use this in place of isblank() so it is inline. Also, unlike 436 * the table implemented ctype(3) routines, this does not have input 437 * range issues caused by sign extensions. 438 * 439 * See mime_header.h for the related is_FWS(). 440 */ 441 static inline int 442 is_WSP(int c) 443 { 444 return c == ' ' || c == '\t'; 445 } 446 447 static inline char * 448 skip_WSP(const char *cp) 449 { 450 while (is_WSP(*cp)) 451 cp++; 452 return __UNCONST(cp); 453 } 454 455 static inline char * 456 skip_space(char *p) 457 { 458 while (isspace((unsigned char)*p)) 459 p++; 460 return p; 461 } 462 463 /* 464 * strip trailing white space 465 */ 466 static inline char * 467 strip_WSP(char *line) 468 { 469 char *cp; 470 471 cp = line + strlen(line) - 1; 472 while (cp >= line && is_WSP(*cp)) 473 cp--; 474 *++cp = '\0'; 475 return cp; 476 } 477 478 #endif /* __DEF_H__ */ 479