[12454] | 1 | |
---|
| 2 | /* |
---|
| 3 | * fmt_scan.c -- format string interpretation |
---|
| 4 | * |
---|
[14730] | 5 | * $Id: fmt_scan.c,v 1.2 2000-05-08 17:38:01 ghudson Exp $ |
---|
[12454] | 6 | */ |
---|
| 7 | |
---|
| 8 | #include <h/mh.h> |
---|
| 9 | #include <h/addrsbr.h> |
---|
| 10 | #include <h/fmt_scan.h> |
---|
| 11 | #include <zotnet/tws/tws.h> |
---|
| 12 | #include <h/fmt_compile.h> |
---|
| 13 | |
---|
| 14 | #define NFMTS MAXARGS |
---|
| 15 | |
---|
| 16 | extern char *formataddr (); /* hook for custom address formatting */ |
---|
| 17 | |
---|
| 18 | #ifdef LBL |
---|
| 19 | struct msgs *fmt_current_folder; /* current folder (set by main program) */ |
---|
| 20 | #endif |
---|
| 21 | |
---|
| 22 | extern int fmt_norm; /* defined in sbr/fmt_def.c = AD_NAME */ |
---|
| 23 | struct mailname fmt_mnull; |
---|
| 24 | |
---|
| 25 | /* |
---|
| 26 | * static prototypes |
---|
| 27 | */ |
---|
| 28 | static int match (char *, char *); |
---|
| 29 | static char *get_x400_friendly (char *, char *, int); |
---|
| 30 | static int get_x400_comp (char *, char *, char *, int); |
---|
| 31 | |
---|
| 32 | |
---|
| 33 | /* |
---|
| 34 | * test if string "sub" appears anywhere in |
---|
| 35 | * string "str" (case insensitive). |
---|
| 36 | */ |
---|
| 37 | |
---|
| 38 | static int |
---|
| 39 | match (char *str, char *sub) |
---|
| 40 | { |
---|
| 41 | int c1, c2; |
---|
| 42 | char *s1, *s2; |
---|
| 43 | |
---|
| 44 | #ifdef LOCALE |
---|
| 45 | while ((c1 = *sub)) { |
---|
| 46 | c1 = (isalpha(c1) && isupper(c1)) ? tolower(c1) : c1; |
---|
| 47 | while ((c2 = *str++) && c1 != ((isalpha(c2) && isupper(c2)) ? tolower(c2) : c2)) |
---|
| 48 | ; |
---|
| 49 | if (! c2) |
---|
| 50 | return 0; |
---|
| 51 | s1 = sub + 1; s2 = str; |
---|
| 52 | while ((c1 = *s1++) && ((isalpha(c1) && isupper(c1)) ? tolower(c1) : c1) == ((isalpha(c2 =*s2++) && isupper(c2)) ? tolower(c2) : c2)) |
---|
| 53 | ; |
---|
| 54 | if (! c1) |
---|
| 55 | return 1; |
---|
| 56 | } |
---|
| 57 | #else |
---|
| 58 | while ((c1 = *sub)) { |
---|
| 59 | while ((c2 = *str++) && (c1 | 040) != (c2 | 040)) |
---|
| 60 | ; |
---|
| 61 | if (! c2) |
---|
| 62 | return 0; |
---|
| 63 | s1 = sub + 1; s2 = str; |
---|
| 64 | while ((c1 = *s1++) && (c1 | 040) == (*s2++ | 040)) |
---|
| 65 | ; |
---|
| 66 | if (! c1) |
---|
| 67 | return 1; |
---|
| 68 | } |
---|
| 69 | #endif |
---|
| 70 | return 1; |
---|
| 71 | } |
---|
| 72 | |
---|
| 73 | /* |
---|
| 74 | * macros to format data |
---|
| 75 | */ |
---|
| 76 | |
---|
| 77 | #define PUTDF(cp, num, wid, fill)\ |
---|
| 78 | if (cp + wid < ep) {\ |
---|
| 79 | if ((i = (num)) < 0)\ |
---|
| 80 | i = -(num);\ |
---|
| 81 | if ((c = (wid)) < 0)\ |
---|
| 82 | c = -c;\ |
---|
| 83 | sp = cp + c;\ |
---|
| 84 | do {\ |
---|
| 85 | *--sp = (i % 10) + '0';\ |
---|
| 86 | i /= 10;\ |
---|
| 87 | } while (i > 0 && sp > cp);\ |
---|
| 88 | if (i > 0)\ |
---|
| 89 | *sp = '?';\ |
---|
| 90 | else if ((num) < 0 && sp > cp)\ |
---|
| 91 | *--sp = '-';\ |
---|
| 92 | while (sp > cp)\ |
---|
| 93 | *--sp = fill;\ |
---|
| 94 | cp += c;\ |
---|
| 95 | } |
---|
| 96 | |
---|
| 97 | #define PUTD(cp, num)\ |
---|
| 98 | if (cp < ep) {\ |
---|
| 99 | if ((i = (num)) == 0)\ |
---|
| 100 | *cp++ = '0';\ |
---|
| 101 | else {\ |
---|
| 102 | if ((i = (num)) < 0) {\ |
---|
| 103 | *cp++ = '-';\ |
---|
| 104 | i = -(num);\ |
---|
| 105 | }\ |
---|
| 106 | c = 10;\ |
---|
| 107 | while (c <= i) \ |
---|
| 108 | c *= 10;\ |
---|
| 109 | while (cp < ep && c > 1) {\ |
---|
| 110 | c /= 10;\ |
---|
| 111 | *cp++ = (i / c) + '0';\ |
---|
| 112 | i %= c;\ |
---|
| 113 | }\ |
---|
| 114 | }\ |
---|
| 115 | } |
---|
| 116 | |
---|
| 117 | #ifdef LOCALE |
---|
| 118 | #define PUTSF(cp, str, wid, fill) {\ |
---|
| 119 | ljust = 0;\ |
---|
| 120 | if ((i = (wid)) < 0) {\ |
---|
| 121 | i = -i;\ |
---|
| 122 | ljust++;\ |
---|
| 123 | }\ |
---|
| 124 | if ((sp = (str))) {\ |
---|
| 125 | if (ljust) {\ |
---|
| 126 | c = strlen(sp);\ |
---|
| 127 | if (c > i)\ |
---|
| 128 | sp += c - i;\ |
---|
| 129 | else {\ |
---|
| 130 | while( --i >= c && cp < ep)\ |
---|
| 131 | *cp++ = fill;\ |
---|
| 132 | i++;\ |
---|
| 133 | }\ |
---|
| 134 | } else {\ |
---|
| 135 | while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ |
---|
| 136 | sp++;\ |
---|
| 137 | }\ |
---|
| 138 | while ((c = (unsigned char) *sp++) && --i >= 0 && cp < ep)\ |
---|
| 139 | if (isgraph(c)) \ |
---|
| 140 | *cp++ = c;\ |
---|
| 141 | else {\ |
---|
| 142 | while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ |
---|
| 143 | sp++;\ |
---|
| 144 | *cp++ = ' ';\ |
---|
| 145 | }\ |
---|
| 146 | }\ |
---|
| 147 | if (!ljust)\ |
---|
| 148 | while( --i >= 0 && cp < ep)\ |
---|
| 149 | *cp++ = fill;\ |
---|
| 150 | } |
---|
| 151 | |
---|
| 152 | #define PUTS(cp, str) {\ |
---|
| 153 | if ((sp = (str))) {\ |
---|
| 154 | while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ |
---|
| 155 | sp++;\ |
---|
| 156 | while((c = (unsigned char) *sp++) && cp < ep)\ |
---|
| 157 | if (isgraph(c)) \ |
---|
| 158 | *cp++ = c;\ |
---|
| 159 | else {\ |
---|
| 160 | while ((c = (unsigned char) *sp) && (iscntrl(c) || isspace(c)))\ |
---|
| 161 | sp++;\ |
---|
| 162 | *cp++ = ' ';\ |
---|
| 163 | }\ |
---|
| 164 | }\ |
---|
| 165 | } |
---|
| 166 | |
---|
| 167 | #else /* LOCALE */ |
---|
| 168 | #define PUTSF(cp, str, wid, fill) {\ |
---|
| 169 | ljust = 0;\ |
---|
| 170 | if ((i = (wid)) < 0) {\ |
---|
| 171 | i = -i;\ |
---|
| 172 | ljust++;\ |
---|
| 173 | }\ |
---|
| 174 | if (sp = (str)) {\ |
---|
| 175 | if (ljust) {\ |
---|
| 176 | c = strlen(sp);\ |
---|
| 177 | if (c > i)\ |
---|
| 178 | sp += c - i;\ |
---|
| 179 | else {\ |
---|
| 180 | while( --i >= c && cp < ep)\ |
---|
| 181 | *cp++ = fill;\ |
---|
| 182 | i++;\ |
---|
| 183 | }\ |
---|
| 184 | } else {\ |
---|
| 185 | while ((c = *sp) && c <= 32)\ |
---|
| 186 | sp++;\ |
---|
| 187 | }\ |
---|
| 188 | while ((c = *sp++) && --i >= 0 && cp < ep)\ |
---|
| 189 | if (c > 32) \ |
---|
| 190 | *cp++ = c;\ |
---|
| 191 | else {\ |
---|
| 192 | while ((c = *sp) && c <= 32)\ |
---|
| 193 | sp++;\ |
---|
| 194 | *cp++ = ' ';\ |
---|
| 195 | }\ |
---|
| 196 | }\ |
---|
| 197 | if (!ljust)\ |
---|
| 198 | while( --i >= 0 && cp < ep)\ |
---|
| 199 | *cp++ = fill;\ |
---|
| 200 | } |
---|
| 201 | |
---|
| 202 | #define PUTS(cp, str) {\ |
---|
| 203 | if (sp = (str)) {\ |
---|
| 204 | while ((c = *sp) && c <= 32)\ |
---|
| 205 | sp++;\ |
---|
| 206 | while( (c = *sp++) && cp < ep)\ |
---|
| 207 | if ( c > 32 ) \ |
---|
| 208 | *cp++ = c;\ |
---|
| 209 | else {\ |
---|
| 210 | while ( (c = *sp) && c <= 32 )\ |
---|
| 211 | sp++;\ |
---|
| 212 | *cp++ = ' ';\ |
---|
| 213 | }\ |
---|
| 214 | }\ |
---|
| 215 | } |
---|
| 216 | |
---|
| 217 | #endif /* LOCALE */ |
---|
| 218 | |
---|
| 219 | |
---|
| 220 | static char *lmonth[] = { "January", "February","March", "April", |
---|
| 221 | "May", "June", "July", "August", |
---|
| 222 | "September","October", "November","December" }; |
---|
| 223 | |
---|
| 224 | static char * |
---|
| 225 | get_x400_friendly (char *mbox, char *buffer, int buffer_len) |
---|
| 226 | { |
---|
| 227 | char given[BUFSIZ], surname[BUFSIZ]; |
---|
| 228 | |
---|
| 229 | if (mbox == NULL) |
---|
| 230 | return NULL; |
---|
| 231 | if (*mbox == '"') |
---|
| 232 | mbox++; |
---|
| 233 | if (*mbox != '/') |
---|
| 234 | return NULL; |
---|
| 235 | |
---|
| 236 | if (get_x400_comp (mbox, "/PN=", buffer, buffer_len)) { |
---|
| 237 | for (mbox = buffer; mbox = strchr(mbox, '.'); ) |
---|
| 238 | *mbox++ = ' '; |
---|
| 239 | |
---|
| 240 | return buffer; |
---|
| 241 | } |
---|
| 242 | |
---|
| 243 | if (!get_x400_comp (mbox, "/S=", surname, sizeof(surname))) |
---|
| 244 | return NULL; |
---|
| 245 | |
---|
| 246 | if (get_x400_comp (mbox, "/G=", given, sizeof(given))) |
---|
| 247 | snprintf (buffer, buffer_len, "%s %s", given, surname); |
---|
| 248 | else |
---|
| 249 | snprintf (buffer, buffer_len, "%s", surname); |
---|
| 250 | |
---|
| 251 | return buffer; |
---|
| 252 | } |
---|
| 253 | |
---|
| 254 | static int |
---|
| 255 | get_x400_comp (char *mbox, char *key, char *buffer, int buffer_len) |
---|
| 256 | { |
---|
| 257 | int idx; |
---|
| 258 | char *cp; |
---|
| 259 | |
---|
| 260 | if ((idx = stringdex (key, mbox)) < 0 |
---|
| 261 | || !(cp = strchr(mbox += idx + strlen (key), '/'))) |
---|
| 262 | return 0; |
---|
| 263 | |
---|
| 264 | snprintf (buffer, buffer_len, "%*.*s", cp - mbox, cp - mbox, mbox); |
---|
| 265 | return 1; |
---|
| 266 | } |
---|
| 267 | |
---|
| 268 | struct format * |
---|
| 269 | fmt_scan (struct format *format, char *scanl, int width, int *dat) |
---|
| 270 | { |
---|
| 271 | char *cp, *ep, *sp; |
---|
| 272 | char *savestr, *str = NULL; |
---|
| 273 | char buffer[BUFSIZ], buffer2[BUFSIZ]; |
---|
| 274 | int i, c, ljust; |
---|
| 275 | int value = 0; |
---|
| 276 | time_t t; |
---|
| 277 | struct format *fmt; |
---|
| 278 | struct comp *comp; |
---|
| 279 | struct tws *tws; |
---|
| 280 | struct mailname *mn; |
---|
| 281 | |
---|
| 282 | cp = scanl; |
---|
| 283 | ep = scanl + width - 1; |
---|
| 284 | fmt = format; |
---|
| 285 | |
---|
| 286 | while (cp < ep) { |
---|
| 287 | switch (fmt->f_type) { |
---|
| 288 | |
---|
| 289 | case FT_COMP: |
---|
| 290 | PUTS (cp, fmt->f_comp->c_text); |
---|
| 291 | break; |
---|
| 292 | case FT_COMPF: |
---|
| 293 | PUTSF (cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill); |
---|
| 294 | break; |
---|
| 295 | |
---|
| 296 | case FT_LIT: |
---|
| 297 | sp = fmt->f_text; |
---|
| 298 | while( (c = *sp++) && cp < ep) |
---|
| 299 | *cp++ = c; |
---|
| 300 | break; |
---|
| 301 | case FT_LITF: |
---|
| 302 | sp = fmt->f_text; |
---|
| 303 | ljust = 0; |
---|
| 304 | i = fmt->f_width; |
---|
| 305 | if (i < 0) { |
---|
| 306 | i = -i; |
---|
| 307 | ljust++; /* XXX should do something with this */ |
---|
| 308 | } |
---|
| 309 | while( (c = *sp++) && --i >= 0 && cp < ep) |
---|
| 310 | *cp++ = c; |
---|
| 311 | while( --i >= 0 && cp < ep) |
---|
| 312 | *cp++ = fmt->f_fill; |
---|
| 313 | break; |
---|
| 314 | |
---|
| 315 | case FT_STR: |
---|
| 316 | PUTS (cp, str); |
---|
| 317 | break; |
---|
| 318 | case FT_STRF: |
---|
| 319 | PUTSF (cp, str, fmt->f_width, fmt->f_fill); |
---|
| 320 | break; |
---|
| 321 | case FT_STRFW: |
---|
| 322 | adios (NULL, "internal error (FT_STRFW)"); |
---|
| 323 | |
---|
| 324 | case FT_NUM: |
---|
| 325 | PUTD (cp, value); |
---|
| 326 | break; |
---|
| 327 | case FT_NUMF: |
---|
| 328 | PUTDF (cp, value, fmt->f_width, fmt->f_fill); |
---|
| 329 | break; |
---|
| 330 | |
---|
| 331 | case FT_CHAR: |
---|
| 332 | *cp++ = fmt->f_char; |
---|
| 333 | break; |
---|
| 334 | |
---|
| 335 | case FT_DONE: |
---|
| 336 | goto finished; |
---|
| 337 | |
---|
| 338 | case FT_IF_S: |
---|
| 339 | if (!(value = (str && *str))) { |
---|
| 340 | fmt += fmt->f_skip; |
---|
| 341 | continue; |
---|
| 342 | } |
---|
| 343 | break; |
---|
| 344 | |
---|
| 345 | case FT_IF_S_NULL: |
---|
| 346 | if (!(value = (str == NULL || *str == 0))) { |
---|
| 347 | fmt += fmt->f_skip; |
---|
| 348 | continue; |
---|
| 349 | } |
---|
| 350 | break; |
---|
| 351 | |
---|
| 352 | case FT_IF_V_EQ: |
---|
| 353 | if (value != fmt->f_value) { |
---|
| 354 | fmt += fmt->f_skip; |
---|
| 355 | continue; |
---|
| 356 | } |
---|
| 357 | break; |
---|
| 358 | |
---|
| 359 | case FT_IF_V_NE: |
---|
| 360 | if (value == fmt->f_value) { |
---|
| 361 | fmt += fmt->f_skip; |
---|
| 362 | continue; |
---|
| 363 | } |
---|
| 364 | break; |
---|
| 365 | |
---|
| 366 | case FT_IF_V_GT: |
---|
| 367 | if (value <= fmt->f_value) { |
---|
| 368 | fmt += fmt->f_skip; |
---|
| 369 | continue; |
---|
| 370 | } |
---|
| 371 | break; |
---|
| 372 | |
---|
| 373 | case FT_IF_MATCH: |
---|
| 374 | if (!(value = (str && match (str, fmt->f_text)))) { |
---|
| 375 | fmt += fmt->f_skip; |
---|
| 376 | continue; |
---|
| 377 | } |
---|
| 378 | break; |
---|
| 379 | |
---|
| 380 | case FT_V_MATCH: |
---|
| 381 | if (str) |
---|
| 382 | value = match (str, fmt->f_text); |
---|
| 383 | else |
---|
| 384 | value = 0; |
---|
| 385 | break; |
---|
| 386 | |
---|
| 387 | case FT_IF_AMATCH: |
---|
| 388 | if (!(value = (str && uprf (str, fmt->f_text)))) { |
---|
| 389 | fmt += fmt->f_skip; |
---|
| 390 | continue; |
---|
| 391 | } |
---|
| 392 | break; |
---|
| 393 | |
---|
| 394 | case FT_V_AMATCH: |
---|
| 395 | value = uprf (str, fmt->f_text); |
---|
| 396 | break; |
---|
| 397 | |
---|
| 398 | case FT_S_NONNULL: |
---|
| 399 | value = (str != NULL && *str != 0); |
---|
| 400 | break; |
---|
| 401 | |
---|
| 402 | case FT_S_NULL: |
---|
| 403 | value = (str == NULL || *str == 0); |
---|
| 404 | break; |
---|
| 405 | |
---|
| 406 | case FT_V_EQ: |
---|
| 407 | value = (fmt->f_value == value); |
---|
| 408 | break; |
---|
| 409 | |
---|
| 410 | case FT_V_NE: |
---|
| 411 | value = (fmt->f_value != value); |
---|
| 412 | break; |
---|
| 413 | |
---|
| 414 | case FT_V_GT: |
---|
| 415 | value = (fmt->f_value > value); |
---|
| 416 | break; |
---|
| 417 | |
---|
| 418 | case FT_GOTO: |
---|
| 419 | fmt += fmt->f_skip; |
---|
| 420 | continue; |
---|
| 421 | |
---|
| 422 | case FT_NOP: |
---|
| 423 | break; |
---|
| 424 | |
---|
| 425 | case FT_LS_COMP: |
---|
| 426 | str = fmt->f_comp->c_text; |
---|
| 427 | break; |
---|
| 428 | case FT_LS_LIT: |
---|
| 429 | str = fmt->f_text; |
---|
| 430 | break; |
---|
| 431 | case FT_LS_GETENV: |
---|
| 432 | if (!(str = getenv (fmt->f_text))) |
---|
| 433 | str = ""; |
---|
| 434 | break; |
---|
| 435 | case FT_LS_CFIND: |
---|
| 436 | if (!(str = context_find (fmt->f_text))) |
---|
| 437 | str = ""; |
---|
| 438 | break; |
---|
| 439 | |
---|
| 440 | case FT_LS_DECODECOMP: |
---|
| 441 | if (decode_rfc2047(fmt->f_comp->c_text, buffer2)) |
---|
| 442 | str = buffer2; |
---|
| 443 | else |
---|
| 444 | str = fmt->f_comp->c_text; |
---|
| 445 | break; |
---|
| 446 | |
---|
| 447 | case FT_LS_DECODE: |
---|
| 448 | if (str && decode_rfc2047(str, buffer2)) |
---|
| 449 | str = buffer2; |
---|
| 450 | break; |
---|
| 451 | |
---|
| 452 | case FT_LS_TRIM: |
---|
| 453 | if (str) { |
---|
| 454 | char *xp; |
---|
| 455 | |
---|
| 456 | strncpy(buffer, str, sizeof(buffer)); |
---|
| 457 | str = buffer; |
---|
| 458 | while (isspace(*str)) |
---|
| 459 | str++; |
---|
| 460 | ljust = 0; |
---|
| 461 | if ((i = fmt->f_width) < 0) { |
---|
| 462 | i = -i; |
---|
| 463 | ljust++; |
---|
| 464 | } |
---|
| 465 | |
---|
| 466 | if (!ljust && i > 0 && strlen(str) > i) |
---|
| 467 | str[i] = '\0'; |
---|
| 468 | xp = str; |
---|
| 469 | xp += strlen(str) - 1; |
---|
| 470 | while (xp > str && isspace(*xp)) |
---|
| 471 | *xp-- = '\0'; |
---|
| 472 | if (ljust && i > 0 && strlen(str) > i) |
---|
| 473 | str += strlen(str) - i; |
---|
| 474 | } |
---|
| 475 | break; |
---|
| 476 | |
---|
| 477 | case FT_LV_COMPFLAG: |
---|
| 478 | value = fmt->f_comp->c_flags; |
---|
| 479 | break; |
---|
| 480 | case FT_LV_COMP: |
---|
| 481 | value = (comp = fmt->f_comp)->c_text ? atoi(comp->c_text) : 0; |
---|
| 482 | break; |
---|
| 483 | case FT_LV_LIT: |
---|
| 484 | value = fmt->f_value; |
---|
| 485 | break; |
---|
| 486 | case FT_LV_DAT: |
---|
| 487 | value = dat[fmt->f_value]; |
---|
| 488 | break; |
---|
| 489 | case FT_LV_STRLEN: |
---|
| 490 | value = strlen(str); |
---|
| 491 | break; |
---|
| 492 | case FT_LV_CHAR_LEFT: |
---|
| 493 | value = width - (cp - scanl); |
---|
| 494 | break; |
---|
| 495 | case FT_LV_PLUS_L: |
---|
| 496 | value += fmt->f_value; |
---|
| 497 | break; |
---|
| 498 | case FT_LV_MINUS_L: |
---|
| 499 | value = fmt->f_value - value; |
---|
| 500 | break; |
---|
| 501 | case FT_LV_DIVIDE_L: |
---|
| 502 | if (fmt->f_value) |
---|
| 503 | value = value / fmt->f_value; |
---|
| 504 | else |
---|
| 505 | value = 0; |
---|
| 506 | break; |
---|
| 507 | case FT_LV_MODULO_L: |
---|
| 508 | if (fmt->f_value) |
---|
| 509 | value = value % fmt->f_value; |
---|
| 510 | else |
---|
| 511 | value = 0; |
---|
| 512 | break; |
---|
| 513 | case FT_SAVESTR: |
---|
| 514 | savestr = str; |
---|
| 515 | break; |
---|
| 516 | |
---|
| 517 | case FT_LV_SEC: |
---|
| 518 | value = fmt->f_comp->c_tws->tw_sec; |
---|
| 519 | break; |
---|
| 520 | case FT_LV_MIN: |
---|
| 521 | value = fmt->f_comp->c_tws->tw_min; |
---|
| 522 | break; |
---|
| 523 | case FT_LV_HOUR: |
---|
| 524 | value = fmt->f_comp->c_tws->tw_hour; |
---|
| 525 | break; |
---|
| 526 | case FT_LV_MDAY: |
---|
| 527 | value = fmt->f_comp->c_tws->tw_mday; |
---|
| 528 | break; |
---|
| 529 | case FT_LV_MON: |
---|
| 530 | value = fmt->f_comp->c_tws->tw_mon + 1; |
---|
| 531 | break; |
---|
| 532 | case FT_LS_MONTH: |
---|
| 533 | str = tw_moty[fmt->f_comp->c_tws->tw_mon]; |
---|
| 534 | break; |
---|
| 535 | case FT_LS_LMONTH: |
---|
| 536 | str = lmonth[fmt->f_comp->c_tws->tw_mon]; |
---|
| 537 | break; |
---|
| 538 | case FT_LS_ZONE: |
---|
| 539 | str = dtwszone (fmt->f_comp->c_tws); |
---|
| 540 | break; |
---|
| 541 | case FT_LV_YEAR: |
---|
| 542 | value = fmt->f_comp->c_tws->tw_year; |
---|
| 543 | break; |
---|
| 544 | case FT_LV_WDAY: |
---|
| 545 | if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP))) |
---|
| 546 | set_dotw (tws); |
---|
| 547 | value = tws->tw_wday; |
---|
| 548 | break; |
---|
| 549 | case FT_LS_DAY: |
---|
| 550 | if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP))) |
---|
| 551 | set_dotw (tws); |
---|
| 552 | str = tw_dotw[tws->tw_wday]; |
---|
| 553 | break; |
---|
| 554 | case FT_LS_WEEKDAY: |
---|
| 555 | if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP))) |
---|
| 556 | set_dotw (tws); |
---|
| 557 | str = tw_ldotw[tws->tw_wday]; |
---|
| 558 | break; |
---|
| 559 | case FT_LV_YDAY: |
---|
| 560 | value = fmt->f_comp->c_tws->tw_yday; |
---|
| 561 | break; |
---|
| 562 | case FT_LV_ZONE: |
---|
| 563 | value = fmt->f_comp->c_tws->tw_zone; |
---|
| 564 | break; |
---|
| 565 | case FT_LV_CLOCK: |
---|
| 566 | if ((value = fmt->f_comp->c_tws->tw_clock) == 0) |
---|
| 567 | value = dmktime(fmt->f_comp->c_tws); |
---|
| 568 | break; |
---|
| 569 | case FT_LV_RCLOCK: |
---|
| 570 | if ((value = fmt->f_comp->c_tws->tw_clock) == 0) |
---|
| 571 | value = dmktime(fmt->f_comp->c_tws); |
---|
| 572 | value = time((time_t *) 0) - value; |
---|
| 573 | break; |
---|
| 574 | case FT_LV_DAYF: |
---|
| 575 | if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP))) |
---|
| 576 | set_dotw (tws); |
---|
| 577 | switch (fmt->f_comp->c_tws->tw_flags & TW_SDAY) { |
---|
| 578 | case TW_SEXP: |
---|
| 579 | value = 1; break; |
---|
| 580 | case TW_SIMP: |
---|
| 581 | value = 0; break; |
---|
| 582 | default: |
---|
| 583 | value = -1; break; |
---|
| 584 | } |
---|
| 585 | case FT_LV_ZONEF: |
---|
| 586 | if ((fmt->f_comp->c_tws->tw_flags & TW_SZONE) == TW_SZEXP) |
---|
| 587 | value = 1; |
---|
| 588 | else |
---|
| 589 | value = -1; |
---|
| 590 | break; |
---|
| 591 | case FT_LV_DST: |
---|
| 592 | value = fmt->f_comp->c_tws->tw_flags & TW_DST; |
---|
| 593 | break; |
---|
| 594 | case FT_LS_822DATE: |
---|
| 595 | str = dasctime (fmt->f_comp->c_tws , TW_ZONE); |
---|
| 596 | break; |
---|
| 597 | case FT_LS_PRETTY: |
---|
| 598 | str = dasctime (fmt->f_comp->c_tws, TW_NULL); |
---|
| 599 | break; |
---|
| 600 | |
---|
| 601 | case FT_LS_PERS: |
---|
| 602 | str = fmt->f_comp->c_mn->m_pers; |
---|
| 603 | break; |
---|
| 604 | case FT_LS_MBOX: |
---|
| 605 | str = fmt->f_comp->c_mn->m_mbox; |
---|
| 606 | break; |
---|
| 607 | case FT_LS_HOST: |
---|
| 608 | str = fmt->f_comp->c_mn->m_host; |
---|
| 609 | break; |
---|
| 610 | case FT_LS_PATH: |
---|
| 611 | str = fmt->f_comp->c_mn->m_path; |
---|
| 612 | break; |
---|
| 613 | case FT_LS_GNAME: |
---|
| 614 | str = fmt->f_comp->c_mn->m_gname; |
---|
| 615 | break; |
---|
| 616 | case FT_LS_NOTE: |
---|
| 617 | str = fmt->f_comp->c_mn->m_note; |
---|
| 618 | break; |
---|
| 619 | case FT_LS_822ADDR: |
---|
| 620 | str = adrformat( fmt->f_comp->c_mn ); |
---|
| 621 | break; |
---|
| 622 | case FT_LV_HOSTTYPE: |
---|
| 623 | value = fmt->f_comp->c_mn->m_type; |
---|
| 624 | break; |
---|
| 625 | case FT_LV_INGRPF: |
---|
| 626 | value = fmt->f_comp->c_mn->m_ingrp; |
---|
| 627 | break; |
---|
| 628 | case FT_LV_NOHOSTF: |
---|
| 629 | value = fmt->f_comp->c_mn->m_nohost; |
---|
| 630 | break; |
---|
| 631 | case FT_LS_ADDR: |
---|
| 632 | case FT_LS_FRIENDLY: |
---|
| 633 | if ((mn = fmt->f_comp->c_mn) == &fmt_mnull) { |
---|
| 634 | str = fmt->f_comp->c_text; |
---|
| 635 | break; |
---|
| 636 | } |
---|
| 637 | if (fmt->f_type == FT_LS_ADDR) |
---|
| 638 | goto unfriendly; |
---|
| 639 | if ((str = mn->m_pers) == NULL) |
---|
| 640 | if ((str = mn->m_note)) { |
---|
| 641 | strncpy (buffer, str, sizeof(buffer)); |
---|
| 642 | str = buffer; |
---|
| 643 | if (*str == '(') |
---|
| 644 | str++; |
---|
| 645 | sp = str + strlen(str) - 1; |
---|
| 646 | if (*sp == ')') { |
---|
| 647 | *sp-- = '\0'; |
---|
| 648 | while (sp >= str) |
---|
| 649 | if (*sp == ' ') |
---|
| 650 | *sp-- = '\0'; |
---|
| 651 | else |
---|
| 652 | break; |
---|
| 653 | } |
---|
| 654 | } else if (!(str = get_x400_friendly (mn->m_mbox, |
---|
| 655 | buffer, sizeof(buffer)))) { |
---|
| 656 | unfriendly: ; |
---|
| 657 | switch (mn->m_type) { |
---|
| 658 | case LOCALHOST: |
---|
| 659 | str = mn->m_mbox; |
---|
| 660 | break; |
---|
| 661 | case UUCPHOST: |
---|
| 662 | snprintf (buffer, sizeof(buffer), "%s!%s", |
---|
| 663 | mn->m_host, mn->m_mbox); |
---|
| 664 | str = buffer; |
---|
| 665 | break; |
---|
| 666 | default: |
---|
| 667 | if (mn->m_mbox) { |
---|
| 668 | snprintf (buffer, sizeof(buffer), "%s@%s", |
---|
| 669 | mn->m_mbox, mn->m_host); |
---|
| 670 | str= buffer; |
---|
| 671 | } |
---|
| 672 | else |
---|
| 673 | str = mn->m_text; |
---|
| 674 | break; |
---|
| 675 | } |
---|
| 676 | } |
---|
| 677 | break; |
---|
| 678 | |
---|
| 679 | case FT_LOCALDATE: |
---|
| 680 | comp = fmt->f_comp; |
---|
| 681 | if ((t = comp->c_tws->tw_clock) == 0) |
---|
| 682 | t = dmktime(comp->c_tws); |
---|
| 683 | tws = dlocaltime(&t); |
---|
| 684 | *comp->c_tws = *tws; |
---|
| 685 | break; |
---|
| 686 | |
---|
| 687 | case FT_GMTDATE: |
---|
| 688 | comp = fmt->f_comp; |
---|
| 689 | if ((t = comp->c_tws->tw_clock) == 0) |
---|
| 690 | t = dmktime(comp->c_tws); |
---|
| 691 | tws = dgmtime(&t); |
---|
| 692 | *comp->c_tws = *tws; |
---|
| 693 | break; |
---|
| 694 | |
---|
| 695 | case FT_PARSEDATE: |
---|
| 696 | comp = fmt->f_comp; |
---|
| 697 | if ((sp = comp->c_text) && (tws = dparsetime(sp))) { |
---|
| 698 | *comp->c_tws = *tws; |
---|
| 699 | comp->c_flags = 0; |
---|
| 700 | } else if (comp->c_flags >= 0) { |
---|
| 701 | memset ((char *) comp->c_tws, 0, sizeof *comp->c_tws); |
---|
| 702 | comp->c_flags = 1; |
---|
| 703 | } |
---|
| 704 | break; |
---|
| 705 | |
---|
| 706 | case FT_FORMATADDR: |
---|
| 707 | /* hook for custom address list formatting (see replsbr.c) */ |
---|
| 708 | str = formataddr (savestr, str); |
---|
| 709 | break; |
---|
| 710 | |
---|
| 711 | case FT_PUTADDR: |
---|
| 712 | /* output the str register as an address component, |
---|
| 713 | * splitting it into multiple lines if necessary. The |
---|
| 714 | * value reg. contains the max line length. The lit. |
---|
| 715 | * field may contain a string to prepend to the result |
---|
| 716 | * (e.g., "To: ") |
---|
| 717 | */ |
---|
| 718 | { |
---|
| 719 | char *lp, *lastb; |
---|
| 720 | int indent, wid, len; |
---|
| 721 | |
---|
| 722 | lp = str; |
---|
| 723 | wid = value; |
---|
| 724 | len = strlen (str); |
---|
| 725 | sp = fmt->f_text; |
---|
| 726 | indent = strlen (sp); |
---|
| 727 | wid -= indent; |
---|
| 728 | while( (c = *sp++) && cp < ep) |
---|
| 729 | *cp++ = c; |
---|
| 730 | while (len > wid) { |
---|
| 731 | /* try to break at a comma; failing that, break at a |
---|
[14730] | 732 | * space, failing that, print the whole address |
---|
[12454] | 733 | */ |
---|
| 734 | lastb = 0; sp = lp + wid; |
---|
| 735 | while (sp > lp && (c = *--sp) != ',') { |
---|
| 736 | if (! lastb && isspace(c)) |
---|
| 737 | lastb = sp - 1; |
---|
| 738 | } |
---|
| 739 | if (sp == lp) |
---|
[14730] | 740 | if (! (sp = lastb)) { /* If no ',' or ' ', */ |
---|
[12454] | 741 | sp = lp + wid - 1; |
---|
[14730] | 742 | while (c = *++sp) { /* then search forward. */ |
---|
| 743 | if (c == ',') |
---|
| 744 | break; |
---|
| 745 | if (isspace(c)) { |
---|
| 746 | --sp; |
---|
| 747 | break; |
---|
| 748 | } |
---|
| 749 | } |
---|
| 750 | if (! *sp) /* If we didn't find comma or space */ |
---|
| 751 | break; /* then PUTS the whole str now */ |
---|
| 752 | } |
---|
[12454] | 753 | len -= sp - lp + 1; |
---|
| 754 | while (cp < ep && lp <= sp) |
---|
| 755 | *cp++ = *lp++; |
---|
| 756 | *cp++ = '\n'; |
---|
| 757 | for (i=indent; cp < ep && i > 0; i--) |
---|
| 758 | *cp++ = ' '; |
---|
| 759 | while (isspace(*lp)) |
---|
| 760 | lp++, len--; |
---|
| 761 | } |
---|
| 762 | PUTS (cp, lp); |
---|
| 763 | } |
---|
| 764 | break; |
---|
| 765 | |
---|
| 766 | case FT_PARSEADDR: |
---|
| 767 | comp = fmt->f_comp; |
---|
| 768 | if (comp->c_mn != &fmt_mnull) |
---|
| 769 | mnfree (comp->c_mn); |
---|
| 770 | if ((sp = comp->c_text) && (sp = getname(sp)) && |
---|
| 771 | (mn = getm (sp, NULL, 0, fmt_norm, NULL))) { |
---|
| 772 | comp->c_mn = mn; |
---|
| 773 | while (getname("")) |
---|
| 774 | ; |
---|
| 775 | } else { |
---|
| 776 | while (getname("")) /* XXX */ |
---|
| 777 | ; |
---|
| 778 | comp->c_mn = &fmt_mnull; |
---|
| 779 | } |
---|
| 780 | break; |
---|
| 781 | |
---|
| 782 | case FT_MYMBOX: |
---|
| 783 | /* |
---|
| 784 | * if there's no component, we say true. Otherwise we |
---|
| 785 | * say "true" only if we can parse the address and it |
---|
| 786 | * matches one of our addresses. |
---|
| 787 | */ |
---|
| 788 | comp = fmt->f_comp; |
---|
| 789 | if (comp->c_mn != &fmt_mnull) |
---|
| 790 | mnfree (comp->c_mn); |
---|
| 791 | if ((sp = comp->c_text) && (sp = getname(sp)) && |
---|
| 792 | (mn = getm (sp, NULL, 0, AD_NAME, NULL))) { |
---|
| 793 | comp->c_mn = mn; |
---|
| 794 | comp->c_flags = ismymbox(mn); |
---|
| 795 | while ((sp = getname(sp))) |
---|
| 796 | if (comp->c_flags == 0 && |
---|
| 797 | (mn = getm (sp, NULL, 0, AD_NAME, NULL))) |
---|
| 798 | comp->c_flags |= ismymbox(mn); |
---|
| 799 | } else { |
---|
| 800 | while (getname("")) /* XXX */ |
---|
| 801 | ; |
---|
| 802 | comp->c_flags = (comp->c_text == 0); |
---|
| 803 | comp->c_mn = &fmt_mnull; |
---|
| 804 | } |
---|
| 805 | break; |
---|
| 806 | |
---|
| 807 | case FT_ADDTOSEQ: |
---|
| 808 | #ifdef LBL |
---|
| 809 | /* If we're working on a folder (as opposed to a file), add the |
---|
| 810 | * current msg to sequence given in literal field. Don't |
---|
| 811 | * disturb string or value registers. |
---|
| 812 | */ |
---|
| 813 | if (fmt_current_folder) |
---|
| 814 | seq_addmsg(fmt_current_folder, fmt->f_text, dat[0], -1); |
---|
| 815 | #endif |
---|
| 816 | break; |
---|
| 817 | } |
---|
| 818 | fmt++; |
---|
| 819 | } |
---|
| 820 | #ifndef JLR |
---|
| 821 | finished:; |
---|
| 822 | if (cp[-1] != '\n') |
---|
| 823 | *cp++ = '\n'; |
---|
| 824 | *cp = 0; |
---|
| 825 | return ((struct format *)0); |
---|
| 826 | #else /* JLR */ |
---|
| 827 | if (cp[-1] != '\n') |
---|
| 828 | *cp++ = '\n'; |
---|
| 829 | while (fmt->f_type != FT_DONE) |
---|
| 830 | fmt++; |
---|
| 831 | |
---|
| 832 | finished:; |
---|
| 833 | *cp = '\0'; |
---|
| 834 | return (fmt->f_value ? ++fmt : (struct format *) 0); |
---|
| 835 | |
---|
| 836 | #endif /* JLR */ |
---|
| 837 | } |
---|