1: 2: /* @(#)misc.c 1.5 92/02/17 3: * 4: * Copyright (c) Steve Holden and Rich Burridge. 5: * All rights reserved. 6: * 7: * Permission is given to distribute these sources, as long as the 8: * copyright messages are not removed, and no monies are exchanged. 9: * 10: * No responsibility is taken for any errors inherent either 11: * to the comments or the code of this program, but if reported 12: * to me then an attempt will be made to fix them. 13: */ 14: 15: #include "mp.h" 16: #include "patchlevel.h" 17: #include "extern.h" 18: 19: 20: void 21: do_date() /* Output Postscript definition for the date and time. */ 22: { 23: char *ptr ; /* Pointer to current time or date string. */ 24: int len ; 25: long clock ; /* Used by the localtime function call. */ 26: struct tm *tm ; /* Used by the localtime and asctime calls. */ 27: char *timenow ; /* Used to set TimeNow field with users name. */ 28: 29: if (date == NULL) 30: { 31: clock = time((time_t *) 0) ; 32: tm = localtime(&clock) ; 33: ptr = asctime(tm) ; 34: ptr[24] = '\0' ; 35: } 36: else ptr = date ; 37: 38: if (article != TRUE) psdef("TimeNow", ptr) ; 39: else 40: { 41: len = strlen(ptr) ; 42: timenow = malloc((unsigned) (len + 6 + strlen(whoami) + 1)) ; 43: SPRINTF(timenow, "%s - (%s)", ptr, whoami) ; 44: psdef("TimeNow", timenow) ; 45: } 46: } 47: 48: 49: int 50: get_opt(argc, argv, options) 51: int argc ; 52: char **argv, *options ; 53: { 54: char opch, *str, *ptr ; 55: static int flag = 0 ; 56: static int cur_argc ; 57: static char **cur_argv ; 58: 59: if (flag == 0) 60: { 61: cur_argc = argc ; 62: cur_argv = argv ; 63: flag = 1 ; 64: optind = 1 ; 65: } 66: 67: if (cur_argc <= 1) return -1 ; 68: 69: if (--cur_argc >= 1) 70: { 71: str = *++cur_argv ; 72: if (*str != '-') return -1 ; /* Argument is not an option */ 73: else 74: { /* Argument is an option */ 75: if ((ptr = strchr(options, opch = *++str)) != (char *) 0) 76: { 77: ++optind ; 78: optarg = ++str ; /* Point to rest of argument if any */ 79: if ((*++ptr == ':') && (*optarg == '\0')) 80: { 81: if (--cur_argc <= 0) return '?' ; 82: optarg = *++cur_argv ; 83: ++optind ; 84: } 85: return opch ; 86: } 87: else if (opch == '-') 88: { /* End of options */ 89: ++optind ; 90: return -1 ; 91: } 92: else return '?' ; 93: } 94: } 95: return 0 ; /* Should never be reached. */ 96: } 97: 98: 99: int 100: get_options(argc, argv) /* Read and process command line options. */ 101: int argc ; 102: char *argv[] ; 103: { 104: int opch ; 105: 106: while ((opch = get_opt(argc, argv, "aA:CdefFlmop:P:s:t:U:v")) != -1) 107: switch (opch) 108: { 109: case 'a' : article = TRUE ; /* "Article from" format. */ 110: break ; 111: case 'A' : if (!strcmp(optarg, "4")) /* A4 paper size. */ 112: paper_size = A4 ; 113: break ; 114: case 'C' : content = TRUE ; /* Use Content-Length: header. */ 115: break ; 116: case 'd' : digest = TRUE ; /* Print digest. */ 117: break ; 118: case 'e' : elm_if = TRUE ; /* ELM intermediate file format. */ 119: folder = TRUE ; /* Kind of folder. */ 120: break ; 121: case 'F' : print_orig = TRUE ; /* Print originators name. */ 122: break ; 123: case 'f' : if (!strcmp(optarg, "f")) /* Filofax output. */ 124: SPRINTF(proname, "%s/mp.pro.ff.ps", prologue) ; 125: else if (!strcmp(optarg, "p")) /* Franklin Planner. */ 126: SPRINTF(proname, "%s/mp.pro.fp.ps", prologue) ; 127: break ; 128: case 'l' : landscape = TRUE ; /* Landscape printing. */ 129: SPRINTF(proname, "%s/mp.pro.l.ps", prologue) ; 130: break ; 131: case 'm' : folder = TRUE ; /* Print mail folder. */ 132: break ; 133: case 'o' : text_doc = TRUE ; /* Print ordinary text file */ 134: break ; 135: case 'P' : if (!strcmp(optarg, "S")) /* Print PostScript files. */ 136: print_ps = FALSE ; 137: break ; 138: case 'p' : if (strlen(optarg)) 139: STRCPY(proname, optarg) ; /* New prologue file. */ 140: break ; 141: case 's' : if (strlen(optarg)) 142: gsubject = optarg ; /* New subject line. */ 143: break ; 144: case 't' : if (!strcmp(optarg, "m")) /* Time Manager. */ 145: SPRINTF(proname, "%s/mp.pro.tm.ps", prologue) ; 146: else if (!strcmp(optarg, "s")) /* Time/System Int. */ 147: SPRINTF(proname, "%s/mp.pro.ts.ps", prologue) ; 148: break ; 149: case 'U' : if (!strcmp(optarg, "S")) /* US paper size. */ 150: paper_size = US ; 151: break ; 152: case '?' : 153: case 'v' : usage() ; 154: } 155: } 156: 157: 158: void 159: init_setup() /* Set default values for various options. */ 160: { 161: char *c ; 162: int amp_cnt = 0 ; /* Number of ampersands in gecos field. */ 163: int i, len ; 164: int namefields ; /* Number of "words" from passwd gecos. */ 165: int namelength ; /* Maximum number of characters from passwd gecos. */ 166: struct passwd *pp ; 167: 168: #ifdef GECOSFIELDS 169: namefields = GECOSFIELDS ; /* New no. of "words" from passwd gecos. */ 170: #else 171: namefields = NAMEFIELDS ; /* Not supplied; use default. */ 172: #endif /*GECOSFIELDS*/ 173: 174: #ifdef GECOSLENGTH 175: namelength = GECOSLENGTH ; /* New max. no. of chars. from passwd gecos. */ 176: #else 177: namelength = NAMELENGTH ; /* Not supplied; use default. */ 178: #endif /*GECOSLENGTH*/ 179: 180: c = getlogin() ; /* Pointer to users login name. */ 181: if (c == NULL) /* Get username from password file */ 182: { 183: pp = getpwuid(geteuid()) ; 184: if (pp == NULL) c = "printing" ; 185: else c = pp->pw_name ; 186: } 187: owner = malloc((unsigned) (strlen(c) + 1)) ; 188: STRCPY(owner, c) ; 189: whoami = malloc((unsigned) (strlen(c) + 1)) ; /* Save User login name */ 190: STRCPY(whoami, c) ; 191: 192: /* Have a look for the users gecos (normally real name), so that its a bit 193: * more recognisable. If this field is too long, then we need to truncate 194: * sensibly. We also need to check a few things. If we've extracted 195: * namefields "words" or have found a comma, then exit. If an ampersand is 196: * found, this is expanded to the users name in capitals. 197: */ 198: 199: pp = getpwnam(owner) ; 200: if (pp != NULL && pp->pw_gecos && pp->pw_gecos[0] != '\0') 201: { 202: len = strlen(pp->pw_gecos) ; 203: for (i = 0; i < len; i++) 204: if (pp->pw_gecos[i] == '&') amp_cnt++ ; 205: 206: owner = malloc((unsigned) (strlen(pp->pw_gecos) + 207: amp_cnt * strlen(c) + 1)) ; 208: 209: if ((nameptr = getenv("NAME")) != NULL) 210: process_name_field(c, nameptr, namefields, namelength) ; 211: else 212: process_name_field(c, pp->pw_gecos, namefields, namelength) ; 213: } 214: 215: if (text_doc) doc_type = DO_TEXT ; 216: switch (doc_type) 217: { 218: case DO_TEXT : message_for = "Listing for "; 219: digest = FALSE ; 220: break ; 221: case DO_MAIL : message_for = digest ? "Mail digest for " : "Mail for " ; 222: break ; 223: case DO_NEWS : message_for = digest ? "News digest for " : "News for " ; 224: break ; 225: } 226: } 227: 228: 229: /* Extract user name from $NAME or passwd GECOS. */ 230: 231: int 232: process_name_field(c, ptr, fields, length) 233: char *c, *ptr ; 234: int fields, length ; 235: { 236: int i, j, len, n, spaces, slen ; 237: 238: n = spaces = 0 ; 239: slen = strlen(ptr) ; 240: for (i = 0; i < slen; i++) 241: { 242: if (*ptr == ',') break ; 243: else if (*ptr == '&') 244: { 245: if (islower(c[0])) owner[n++] = toupper(c[0]) ; 246: len = strlen(c) ; 247: for (j = 1; j < len; j++) 248: owner[n++] = c[j] ; 249: ptr++ ; 250: } 251: else if (*ptr == ' ' || *ptr == '\t') 252: { 253: if (++spaces == fields) break ; 254: else 255: while (*ptr == ' ' || *ptr == '\t') owner[n++] = *ptr++ ; 256: } 257: else owner[n++] = *ptr++ ; 258: if (n >= length) break ; 259: } 260: if (n > length) n = length ; 261: owner[n] = '\0' ; 262: } 263: 264: 265: int 266: usage() /* Print usage message and exit. */ 267: { 268: FPRINTF(stderr, "%s version 2.5.%1d\n\n", progname, PATCHLEVEL) ; 269: FPRINTF(stderr, "Usage: %s [-A4] [-F] [-PS] [-US] ", progname) ; 270: FPRINTF(stderr, "[-a] [-d] [-e] [-f] [-l] [-m] [-o]\n", progname) ; 271: FPRINTF(stderr, "\t[-p prologue] [-s subject] [-tm] [-ts] [-v] ") ; 272: FPRINTF(stderr, "[-?] filename ...\n") ; 273: exit(1) ; 274: }