PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 1 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 1 /***********************************************************************/ 2 /********************************************************************* 3 * This software is Copyright (C) 1988 by Steven Dorner and the 4 * University of Illinois Board of Trustees, and by CSNET. No warranties of 5 * any kind are expressed or implied. No support will be provided. 6 * This software may not be redistributed without prior consent of CSNET. 7 * You may direct questions to dorner@garcon.cso.uiuc.edu. 8 **********************************************************************/ 9 10 /*********************************************************************** 11 * This is a client program for CSO's nameserver. It attempts to contact 12 * the nameserver running on garcon.cso.uiuc.edu, and query it about 13 * entries. The following entries in /etc/hosts (if you're using one) and 14 * /etc/services will help matters: 15 * 16 * /etc/hosts: 17 * 128.174.5.58 garcon.cso.uiuc.edu garcon 18 * 19 * /etc/services: 20 * ns 105/tcp ns # CSO nameserver 21 *************************************************************************/ 22 #ifdef VMS 23 /* 24 P H for V A X / V M S 25 26 27 Ported to VAX/VMS Version 5.3 using VAXC 3.2 and TGV MultiNet 3.0 28 by Mark Sandrock, UIUC School of Chemical Sciences Computing Services 29 and R. Kevin Oberman, Lawrence Livermore National Laboratory. 30 31 VMS 4.4 implementation notes: 32 33 1) VAXCRTL does not supply the following routines used by PH: 34 35 a) fork -- SYS$CREPRC or LIB$SPAWN should be used instead. 36 b) execlp -- VAXCRTL does provide execl, but it is too limited. 37 c) popen/pclose -- VAXCRTL does provide "pipe" instead. 38 d) index/rindex -- VAXCRTL "strchr/strrchr" functions are equivalent. 39 e) getpass -- implemented in this file. 40 f) unlink -- VAXCRTL does provide "delete" function. 41 42 2) VAX/VMS does not provide the following utilities used by PH: 43 44 a) /usr/ucb/more -- VMS PH does not do paging yet. 45 b) /usr/ucb/vi -- EDT or TPU should be used instead. 46 47 3) The VAXCRTL "getenv" function does not recognize the following 48 environment names. SYS$TRNLNM could be used instead, if need be: 49 50 a) PAGER: specifies "pager" other than the default (TYPE/PAGE). 51 b) EDITOR: specifies editor other than the default (EDT). 52 53 4) The SOCKET INTERFACE implemented by TGV MultiNet 3.0 returns 54 a channel number rather than a standard file descriptor, and thus 55 is not compatible with the UNIX-style i/o functions such as fdopen, PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 2 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 56 read and write. Instead MultiNet provides special versions of read/ 57 write called socket_read/socket_write for network i/o. 58 59 5) The VMS VAXC include files are used wherever possible, with several 60 exceptions as noted in the MultiNet Programmer's Guide. The following 61 include files do not exist under VMS VAXC 3.2 and were simply copied 62 over from uxc (4.3 bsd): 63 64 a) #include 65 b) #include 66 67 Change log: 68 69 05-May-1988 12:09 MTS Initial port of ph.c,v 2.15 to vms_ph.c. 70 Initial port of cryptit.c to vms_cryptit.c. 71 72 13-Feb-1991 16:08 MTS Has it really been that long? Re-ported 73 ph v4.10 under VMS 5.3 and WIN/TCP 5.1. 74 75 15-Oct-1991 14:44 RKO Modified for MultiNet V3.0. 76 /* 77 ***************************************************************************/ 78 79 static char *rcsid = "VAX/VMS: ph.c,v 4.10 91/10/15 14:44:00 sandrock-oberman"; 80 81 #include stdio 343 #include signal 440 #include "multinet_root:[multinet.include.sys]types.h" 507 #include "multinet_root:[multinet.include.sys]socket.h" 658 #include file 679 #include stat 728 #include "multinet_root:[multinet.include.netinet]in.h" 842 #include "multinet_root:[multinet.include]netdb.h" 922 #include ctype 985 /* #include */ 986 #include descrip /* VMS descriptor structures defs */ 1419 #include iodef /* VMS I/O function definitions */ 1983 #include ssdef /* VMS System Status definitions */ 2625 #include ttdef /* VMS terminal characteristics */ 2837 #include "termdefs.h" /* VMS defs for setterm() function */ 2918 2919 #else 2920 X static char *rcsid = "$Date: 91/02/06 07:24:53 $$Revision: 4.10 $"; 2921 X static char *srcid = "$Source: /nameserv/Src/Ph/RCS/ph.c,v $"; 2922 X 2923 X #include 2924 X #include 2925 X #include 2926 X #include 2927 X #include 2928 X #include 2929 X #include 2930 X #include 2931 X #include 2932 X #include 2933 X #include 2934 X #ifdef hpux PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 3 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 2935 X #include 2936 X #define bcopy(source,dest,count) memcpy(dest,source,count) 2937 X #define index(string,ch) strchr(string,ch) 2938 X #define rindex(string,ch) strrchr(string,ch) 2939 X #else 2940 X #ifndef NeXT 2941 X void bcopy(); 2942 X #endif 2943 X #endif 2944 #endif 2945 2946 #include "replies.h" 3003 3004 /*********************************************************************** 3005 * vital defines 3006 ***********************************************************************/ 3007 #define MAXSTR 2048 /* max string length */ 3008 #define MAXVAL 14000 /* max value length */ 3009 #define DELIM " \t\n"/* command delimiters */ 3010 #define MAXARGS 20 /* maximum # of arguments in PH environ var. */ 3011 /*********************************************************************** 3012 * declarations for a couple of useful functions 3013 ***********************************************************************/ 3014 char *GetValue(); 3015 char *strtok(); 3016 char *getenv(); 3017 #ifdef VMS 3018 char *strchr(); /* VMS equivalent of "index" */ 3019 char *strrchr(); /* VMS equivalent of "rindex" */ 3020 #define index(a,b) strchr(a,b) 3021 #define rindex(a,b) strrchr(a,b) 3022 3023 #define GetQValue(aLine) \ 3024 (strchr(strchr(aLine,':')+1,':')+1) 3025 #else 3026 X FILE *popen(); 3027 X 3028 X #define GetQValue(aLine) \ 3029 X (index(index(aLine,':')+1,':')+1) 3030 #endif 3031 char *malloc(); 3032 char *getpass(); 3033 void exit(), free(), perror(); 3034 char *makestr(); 3035 3036 /************************************************************************ 3037 * declarations for the functions in this file 3038 ************************************************************************/ 3039 int main(); 3040 char *issub(); 3041 int ContactQI(); 3042 int DoId(); 3043 int PrintResponse(); 3044 int GetGood(); 3045 void EnvOptions(); 3046 void ComplainAboutService(); 3047 void ComplainAboutHost(); PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 4 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3048 void Interactive(); 3049 int DoCommand(); 3050 int DoOtherWPage(); 3051 int DoOther(); 3052 #ifdef MACC 3053 X int DoFields(); 3054 #endif 3055 int DoHelp(); 3056 int DoQuery(); 3057 /* int DoLogin(); */ 3058 int DoQuit(); 3059 int DoEdit(); 3060 int DoMake(); 3061 int EditValue(); 3062 int UpdateValue(); 3063 int DoFields(); 3064 int DoMe(); 3065 /* int DoPassword(); 3066 int DoLogout(); 3067 void VetPassword(); */ 3068 int AllDigits(); 3069 int PrintQResponse(); 3070 /* void DoAutoLogin(); */ 3071 void SkipMacdef(); 3072 /* int TryLogin(); */ 3073 void EmailLine(); 3074 void NotRegisteredLine(); 3075 FILE *OpenPager(); 3076 int DoSwitch(); 3077 3078 /*********************************************************************** 3079 * These are external for convenience' sake 3080 ***********************************************************************/ 3081 #ifdef MACC_ECHO 3082 X int maccecho =0; 3083 #endif 3084 #ifdef VMS 3085 int ToQI; /* write to this to tell the nameserver stuff */ 3086 int FromQI; /* read nameserver responses from here */ 3087 char ToQIBuf[MAXSTR]; 3088 int ToQILen; 3089 #define qprintf \ 3090 { \ 3091 char *ToQI=ToQIBuf; \ 3092 sprintf 3093 #define qflush(foobar) \ 3094 ToQILen = strlen(ToQIBuf); \ 3095 } \ 3096 socket_write(ToQI,ToQIBuf,ToQILen) 3097 #else 3098 X FILE *ToQI; /* write to this to tell the nameserver stuff */ 3099 X FILE *FromQI; /* read nameserver responses from here */ 3100 X #define qprintf fprintf 3101 X #define qflush fflush 3102 #endif 3103 char MyAlias[MAXSTR]; /* currently logged-in alias */ 3104 char *Me; /* the name of this program */ PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 5 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3105 char *MyPassword=NULL; /* password read from .netrc (if any) */ 3106 /************************************************************************ 3107 * switches 3108 ************************************************************************/ 3109 int NoNetrc = 0; /* -n don't read .netrc */ 3110 char *UseHost = 0; /* -s use server on what machine */ 3111 int UsePort = 0; /* -p use port # */ 3112 int NoReformat=1; /* -i don't reformat email fields */ 3113 int NoPager=0; /* -m don't use pager */ 3114 int NoBeautify=0; /* -b don't beautify output */ 3115 int NoLabels=0; /* -l don't use labels */ 3116 int Confirm=0; /* -c confirm Edit */ 3117 char *DefType=0; /* -t prepend this type to queries */ 3118 char *ReturnFields=NULL;/* -f give list of fields */ 3119 /*********************************************************************** 3120 * and the fun begins... 3121 ***********************************************************************/ 3122 int main(argc, argv) 3123 int argc; 3124 char **argv; 3125 { 3126 1 int theCode=LR_ERROR; 3127 1 int optionsCount; 3128 1 char buffer[4096]; 3129 1 #ifdef MACC_ECHO 3130 X int margc=0; 3131 1 #endif 3132 1 #ifdef VMS 3133 1 char *temps; /* temp strings */ 3134 1 #endif 3135 1 /* 3136 1 * figure out what this program is called 3137 1 */ 3138 1 #ifdef VMS 3139 1 Me = " ph"; 3140 1 #else 3141 X Me = rindex(*argv,'/'); 3142 1 #endif 3143 1 if (Me) 3144 1 Me++; 3145 1 else 3146 1 Me = *argv; 3147 1 EnvOptions(CLIENT); 3148 1 if (strcmp(CLIENT,Me)) 3149 1 { 3150 2 sprintf(buffer,"-t %s",Me); 3151 2 (void) OptionLine(buffer); 3152 2 EnvOptions(Me); 3153 2 } 3154 1 optionsCount = ProcessOptions(--argc,++argv); 3155 1 argc -= optionsCount; 3156 1 argv += optionsCount; 3157 1 3158 1 if (!ContactQI()) 3159 1 { 3160 2 fputs("Sorry--phone book not available now.\n", stderr); 3161 2 #ifdef VMS PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 6 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3162 2 exit(SS$_CONNECFAIL); 3163 2 #else 3164 X exit(1); 3165 2 #endif 3166 2 } 3167 1 3168 1 /* 3169 1 * identify ourselves 3170 1 */ 3171 1 if ((theCode=DoId())>=400) exit(theCode/100); 3172 1 if (argc==0) 3173 1 Interactive(); /* no arguments--interactive mode */ 3174 1 else 3175 1 { 3176 2 /* make a query out of the arguments */ 3177 2 3178 2 strcpy(buffer,"query "); 3179 2 for (; argc; argc--, argv++) 3180 2 { 3181 3 strcat(buffer,*argv); 3182 3 if (argc > 1) 3183 3 strcat(buffer," "); 3184 3 } 3185 2 strcat(buffer,"\n"); 3186 2 theCode = DoCommand(buffer); 3187 2 qprintf(ToQI,"\nquit\n"); 3188 3 qflush(ToQI); 3189 2 } 3190 1 #ifdef VMS 3191 1 exit(SS$_NORMAL); 3192 1 #else 3193 X exit(theCode > 299 ? theCode/100 : 0); 3194 1 #endif 3195 1 } 3196 3197 /*********************************************************************** 3198 * contact the central nameserver 3199 ***********************************************************************/ 3200 int ContactQI() 3201 { 3202 1 int sock; /* our socket */ 3203 1 static struct sockaddr_in QI; /* the address of the nameserver */ 3204 1 struct servent *theNs; /* nameserver service entry */ 3205 1 static struct hostent *theHost; /* host entry for nameserver */ 3206 1 char host[80]; 3207 1 char *baseHost; 3208 1 int backupNum=0; 3209 1 int mightBackup; 3210 1 3211 1 /* create the socket */ 3212 1 sock = socket(PF_INET, SOCK_STREAM, 0); 3213 1 if (sock < 0) 3214 1 return (0); 3215 1 QI.sin_family = AF_INET; 3216 1 3217 1 /* find the proper port */ 3218 1 if (UsePort) PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 7 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3219 1 QI.sin_port = UsePort; 3220 1 else if (theNs = getservbyname(NSSERVICE, "tcp")) 3221 1 { 3222 2 QI.sin_port = theNs->s_port; 3223 2 } 3224 1 else 3225 1 { 3226 2 ComplainAboutService(); 3227 2 QI.sin_port = htons(FALLBACKPORT); 3228 2 } 3229 1 3230 1 /* find the proper host */ 3231 1 baseHost = UseHost ? UseHost : HOST; 3232 1 if (mightBackup=(*baseHost=='.')) 3233 1 sprintf(host,"%s%s",NSSERVICE,baseHost); 3234 1 else 3235 1 strcpy(host,baseHost); 3236 1 3237 1 for (;;) 3238 1 { 3239 2 /* create the socket */ 3240 2 sock = socket(PF_INET, SOCK_STREAM, 0); 3241 2 if (sock < 0) 3242 2 return (0); 3243 2 QI.sin_family = AF_INET; 3244 2 if (theHost = gethostbyname(host)) 3245 2 { 3246 3 bcopy(theHost->h_addr, (char *) &QI.sin_addr.s_addr, 4); 3247 3 } 3248 2 else if (!backupNum) 3249 2 { 3250 3 ComplainAboutHost(host); 3251 3 QI.sin_addr.s_addr = htonl(FALLBACKADDR); 3252 3 theHost = gethostbyaddr(&QI.sin_addr.s_addr, 4, AF_INET); 3253 3 } 3254 2 else 3255 2 { 3256 3 fprintf(stderr,"No more backups to try.\n"); 3257 3 return(0); 3258 3 } 3259 2 3260 2 /* connect to the nameserver */ 3261 2 if (connect(sock, (struct sockaddr *)&QI, sizeof(QI)) < 0) 3262 2 { 3263 3 perror(host); 3264 3 if (mightBackup) 3265 3 { 3266 4 backupNum++; 3267 4 sprintf(host,"%s%d%s",NSSERVICE,backupNum,baseHost); 3268 4 } 3269 3 else 3270 3 return (0); 3271 3 } 3272 2 else break; 3273 2 } 3274 1 3275 1 if (backupNum) PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 8 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3276 1 fprintf(stderr,"WARNING--backup host %s; information may be out of date.\n",host); 3277 1 /* open path to nameserver */ 3278 1 #ifdef VMS 3279 1 ToQI = sock; /* copy socket channel for netwrite calls */ 3280 1 FromQI = sock; /* ditto for netread calls */ 3281 1 #else 3282 X if ((ToQI = fdopen(sock, "w")) == NULL) 3283 X { 3284 X perror("to qi"); 3285 X return (0); 3286 X } 3287 X 3288 X /* open path from nameserver */ 3289 X if ((FromQI = fdopen(sock, "r")) == NULL) 3290 X { 3291 X perror("from qi"); 3292 X return (0); 3293 X } 3294 1 #endif 3295 1 UseHost = theHost->h_name; 3296 1 UsePort = QI.sin_port; 3297 1 3298 1 return (1); 3299 1 } 3300 3301 /*********************************************************************** 3302 * identify ourselves to the nameserver 3303 ***********************************************************************/ 3304 int DoId() 3305 { 3306 1 qprintf(ToQI,"id %d\n",getuid()); 3307 2 qflush(ToQI); 3308 1 return (PrintResponse(-1)); 3309 1 } 3310 3311 /*********************************************************************** 3312 * print what the QI (Query Interpreter; nameserver) says 3313 * read replies from nameserver until code indicates a completed 3314 * command. This routine does not beautify the responses in any way. 3315 * if doPaging is 1, the pager will be used. 3316 * if doPaging is 0, no pager will be used. 3317 * if doPaging is -1, the response will not be printed at all. 3318 ***********************************************************************/ 3319 int PrintResponse(doPaging) 3320 int doPaging; /* use the pager? */ 3321 { 3322 1 char scratch[MAXSTR]; /* some space */ 3323 1 int code=LR_ERROR; /* the reply code */ 3324 1 FILE *theOutput; 3325 1 3326 1 theOutput = OpenPager(doPaging); 3327 1 while (GetGood(scratch, MAXSTR, FromQI)) /* read it */ 3328 1 { 3329 2 code = atoi(scratch); 3330 2 if (doPaging!= -1 || code>=400) fputs(scratch, theOutput); /* echo it */ 3331 2 if (code >= LR_OK) 3332 2 break; PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 9 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3333 2 } 3334 1 #ifdef VMS 3335 1 #else 3336 X if (theOutput != stdout) 3337 X pclose(theOutput); 3338 1 #endif 3339 1 3340 1 return (code); /* all done. return final code */ 3341 1 } 3342 3343 /*********************************************************************** 3344 * get a non-comment line from a stream 3345 * a comment is a line beginning with a # sign 3346 ***********************************************************************/ 3347 int GetGood(theString, maxChars, theFile) 3348 char *theString; /* space to put the chars */ 3349 int maxChars; /* max # of chars we want */ 3350 #ifdef VMS 3351 int theFile; /* stream to read them from */ 3352 { 3353 1 static char Qbuf [MAXSTR+4] = { '\0' } ; 3354 1 static int pos = {0}, end = {0}, len = {0}, tend = {0}; 3355 1 char *linp; 3356 1 3357 1 for (;;) 3358 1 { 3359 2 if (pos >= len) 3360 2 { 3361 3 len = socket_read(theFile,Qbuf,maxChars); 3362 3 if (len <= 0) return (0); 3363 3 Qbuf [len] = '\0'; 3364 3 pos = 0; 3365 3 } 3366 2 3367 2 linp = index(Qbuf+pos, '\n'); /* find next newline char */ 3368 2 if (linp == NULL) 3369 2 { 3370 3 strncpy(theString, Qbuf+pos, len-pos+1); /* Copy what we have */ 3371 3 end = len-pos; /* no newline chars left */ 3372 3 pos = 0; /* Start at the beginning */ 3373 3 len = socket_read(theFile,Qbuf,maxChars); 3374 3 if (len <= 0) return (0); 3375 3 Qbuf [len] = '\0'; 3376 3 linp = index(Qbuf, '\n'); 3377 3 strncpy(theString+end, Qbuf, linp-Qbuf+1); 3378 3 tend = linp + end - Qbuf; 3379 3 *(theString+tend-pos+1) = '\0'; 3380 3 end = tend - end; 3381 3 } 3382 2 else 3383 2 { 3384 3 end = linp - Qbuf; /* convert pointer to index */ 3385 3 strncpy(theString, Qbuf+pos, end-pos+1); 3386 3 *(theString+end-pos+1) = '\0'; 3387 3 } 3388 2 pos = end + 1; /* save new position for next time */ 3389 2 #else PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 10 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3390 X FILE *theFile; /* stream to read them from */ 3391 X { 3392 X for (;;) 3393 X { 3394 X (void) fgets(theString, maxChars, theFile); 3395 2 #endif 3396 2 if (*theString != '#') 3397 2 return (1); /* not a comment; success! */ 3398 2 else 3399 2 if (!*theString) 3400 2 return (0); /* empty string==end of stream */ 3401 2 } 3402 1 } 3403 3404 /*********************************************************************** 3405 * complain that there isn't an entry for ns in /etc/services 3406 ***********************************************************************/ 3407 void ComplainAboutService() 3408 { 3409 1 fprintf(stderr, "Warning--there is no entry for ``%s'' in /etc/services;\n", 3410 1 NSSERVICE); 3411 1 fputs("please have your systems administrator add one.\n", stderr); 3412 1 fprintf(stderr, "I'm going to use port %d in the meantime.\n", FALLBACKPORT); 3413 1 } 3414 3415 /*********************************************************************** 3416 * complain that there isn't an entry for garcon in /etc/hosts 3417 ***********************************************************************/ 3418 void ComplainAboutHost(name) 3419 char *name; 3420 { 3421 1 fprintf(stderr, "Warning--unable to find address for ``%s''.\n", 3422 1 name); 3423 1 fprintf(stderr, "I'm going to use address 0x%x in the meantime.\n", 3424 1 FALLBACKADDR); 3425 1 } 3426 3427 /*********************************************************************** 3428 * the interactive portion of the client 3429 ***********************************************************************/ 3430 typedef struct command Command; 3431 struct command 3432 { 3433 char *cName; /* the name of the command */ 3434 int cLog; /* must be logged in to use? */ 3435 int (*cFunc) (); /* function to call for command */ 3436 }; 3437 3438 Command CommandTable[] = 3439 { 3440 "help", 0, DoHelp, 3441 "?", 0, DoHelp, 3442 "query", 0, DoQuery, 3443 #ifndef MACC 3444 CLIENT, 0, DoQuery, 3445 "me", 1, DoMe, 3446 "edit", 1, DoEdit, PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 11 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3447 "make", 1, DoMake, 3448 "password", 1, DoPassword, %CC-E-UNDECLARED, "DoPassword" is not declared within the scope of this usage. 3449 "passwd", 1, DoPassword, %CC-E-UNDECLARED, "DoPassword" is not declared within the scope of this usage. 3450 "login", 0, DoLogin, %CC-E-UNDECLARED, "DoLogin" is not declared within the scope of this usage. 3451 "logout", 1, DoLogout, %CC-E-UNDECLARED, "DoLogout" is not declared within the scope of this usage. 3452 #endif 3453 #ifdef MACC 3454 X "fields", 0, DoFields, 3455 #else 3456 "fields", 0, DoOtherWPage, 3457 "switch", 0, DoSwitch, 3458 #endif 3459 #ifndef MACC 3460 "add", 1, DoOther, 3461 "delete", 1, DoOther, 3462 "set", 0, DoOther, 3463 #endif 3464 "quit", 0, DoQuit, 3465 "bye", 0, DoQuit, 3466 "exit", 0, DoQuit, 3467 0, 0, 0 3468 }; 3469 3470 /*********************************************************************** 3471 * the main loop 3472 ***********************************************************************/ 3473 int LastCode = 0; /* the response from the previous command */ 3474 void Interactive() 3475 { 3476 1 char inputLine[MAXSTR]; /* space for an input line */ 3477 1 char *spot; 3478 1 3479 1 *MyAlias = 0; /* nobody logged in yet... */ 3480 1 #ifndef MACC 3481 1 puts(rcsid); 3482 1 /* printf("Send mail to %s to get your password (see \"help password\").\n",PASSW); */ 3483 1 printf("Mail other questions or comments to %s.\n",ADMIN); 3484 1 #else 3485 X printf("Lookup - ELECTRONIC MAIL DIRECTORY SERVICE\n\n"); 3486 X printf("Please mail questions or comments to %s.\n",ADMIN); 3487 1 #endif 3488 1 3489 1 /* 3490 1 * print database status 3491 1 */ PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 12 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3492 1 LastCode = DoOther("status\n",0); 3493 1 3494 1 /* 3495 1 * autologin if possible 3496 1 */ 3497 1 /* #ifndef MACC 3498 1 if (!NoNetrc) DoAutoLogin(); 3499 1 #endif */ 3500 1 3501 1 puts(" "); 3502 1 3503 1 while (1) 3504 1 { 3505 2 (void) signal(SIGPIPE,SIG_IGN); 3506 2 #ifdef MACC_ECHO 3507 X if (!maccecho) 3508 X printf("%s> ",Me); 3509 2 #else 3510 2 printf("%s> ",Me); 3511 2 #endif 3512 2 (void) fflush(stdout); /* prompt */ 3513 2 spot=inputLine; 3514 2 do { 3515 3 if (!fgets(spot, MAXSTR-(spot-inputLine), stdin)) 3516 3 return; /* read line */ 3517 3 spot = inputLine + strlen(inputLine)-2; 3518 3 if (*spot=='\\') *spot++ = ' '; 3519 3 else spot=inputLine-1; 3520 3 } 3521 2 while (spot>=inputLine); 3522 2 #ifdef MACC_ECHO 3523 X if (maccecho) 3524 X printf("%s> %s",Me,inputLine); 3525 2 #endif 3526 2 3527 2 if (!(LastCode=DoCommand(inputLine))) /* is it a command we know? */ 3528 2 LastCode = DoOther(inputLine); /* unrecognized command */ 3529 2 } 3530 1 } 3531 3532 /*********************************************************************** 3533 * look at input line, and if we have a specific command for it, do it 3534 ***********************************************************************/ 3535 int DoCommand(inputLine) 3536 char *inputLine; /* the input line */ 3537 { 3538 1 char scratch[MAXSTR]; /* some space */ 3539 1 char *theToken; /* a token from the command line */ 3540 1 Command *theCommand; /* the command name */ 3541 1 Command *doMe; 3542 1 int len; 3543 1 3544 1 /* make a safe copy of the input line, so we can play with it */ 3545 1 strcpy(scratch, inputLine); 3546 1 3547 1 if (!(theToken = strtok(scratch, DELIM))) 3548 1 return (LR_ERROR); /* blank line */ PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 13 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3549 1 3550 1 /* search command table linearly */ 3551 1 doMe = NULL; 3552 1 len = strlen(theToken); 3553 1 for (theCommand = CommandTable; theCommand->cName; theCommand++) 3554 1 if (!strncmp(theCommand->cName, theToken, len)) 3555 1 { 3556 2 if (doMe) /* we found 2 commands that match (bad) */ 3557 2 { 3558 3 printf("%s is ambiguous.\n", theToken); 3559 3 return (LR_ERROR); 3560 3 } 3561 2 doMe = theCommand; /* we found a command that matches */ 3562 2 } 3563 1 3564 1 if (doMe) /* found one and only one command */ 3565 1 { 3566 2 /* expand command name */ 3567 2 theToken = strtok((char *)0, "\n"); 3568 2 sprintf(inputLine, "%s %s\n", doMe->cName, theToken ? theToken : ""); 3569 2 3570 2 /* execute command */ 3571 2 if (doMe->cLog && !*MyAlias) 3572 2 printf("You must be logged in to use %s.\n",doMe->cName); 3573 2 else 3574 2 return((*doMe->cFunc) (inputLine)); 3575 2 return (LR_ERROR); 3576 2 } 3577 1 3578 1 return (0); /* didn't find it */ 3579 1 } 3580 3581 /*********************************************************************** 3582 * execute a command for which we do nothing special; use the pager 3583 ***********************************************************************/ 3584 int DoOtherWPage(inputLine) 3585 char *inputLine; 3586 { 3587 1 qprintf(ToQI,"%s",inputLine); /* send command */ 3588 2 qflush(ToQI); 3589 1 return (PrintResponse(1)); /* get response */ 3590 1 } 3591 3592 /*********************************************************************** 3593 * execute a command for which we do nothing special; don't use pager 3594 ***********************************************************************/ 3595 int DoOther(inputLine) 3596 char *inputLine; 3597 { 3598 1 qprintf(ToQI,"%s",inputLine); /* send command */ 3599 2 qflush(ToQI); 3600 1 return (PrintResponse(0)); /* get response */ 3601 1 } 3602 3603 #ifdef MACC 3604 X int DoFields(inputLine) 3605 X char *inputLine; PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 14 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3606 X { 3607 X printf("Field Name Description\n"); 3608 X printf("------------------------------\n"); 3609 X printf("name Person Name\n"); 3610 X printf("email Electronic Mail Address if exists\n"); 3611 X printf("phone Telephone Number One\n"); 3612 X printf("phone2 Telephone Number Two\n"); 3613 X printf("address Street Address of the Building\n"); 3614 X printf("building Building Name\n"); 3615 X printf("department Department Number One of Person\n"); 3616 X printf("department2 Department number Two of Person\n"); 3617 X printf("appointment Appointment Classification Code Number One \n"); 3618 X printf("appointment2 Appointment Classification Code Number Two\n"); 3619 X printf("title Title One\n"); 3620 X printf("title2 Title Two\n"); 3621 X printf("alias Unique Name built from First Letter of First Name, Last\n"); 3622 X printf(" Name and a Number\n\n"); 3623 X return(LR_OK); 3624 X } 3625 #endif 3626 3627 /*********************************************************************** 3628 * execute a query request 3629 ***********************************************************************/ 3630 int DoQuery(inputLine) 3631 char *inputLine; 3632 { 3633 1 char scratch[4096]; 3634 1 char *args; 3635 1 int noReformatWas = NoReformat; 3636 1 int code; 3637 1 3638 1 if (ReturnFields && !issub(inputLine,"return")) 3639 1 { 3640 2 args=inputLine+strlen(inputLine)-1; 3641 2 sprintf(args," return %s\n",ReturnFields); 3642 2 for (;*args;args++) if (*args==',') *args=' '; 3643 2 } 3644 1 if (!NoBeautify && !NoReformat) 3645 1 { 3646 2 char *ret = issub(inputLine,"return"); 3647 2 if (ret) NoReformat = !issub(ret,"email"); 3648 2 } 3649 1 if (!DefType || issub(inputLine,"type=")) 3650 1 { 3651 2 qprintf(ToQI,"%s",inputLine); /* send command */ 3652 3 qflush(ToQI); 3653 2 } 3654 1 else 3655 1 { 3656 2 strcpy(scratch,inputLine); 3657 2 args = strtok(scratch," \t"); 3658 2 args = strtok(0,"\n"); 3659 2 if (args) 3660 2 { 3661 3 qprintf(ToQI,"query type=\"%s\" %s\n",DefType,args); /* send command */ 3662 4 qflush(ToQI); PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 15 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3663 3 } 3664 2 else 3665 2 { 3666 3 qprintf(ToQI,"%s",inputLine); 3667 4 qflush(ToQI); 3668 3 } 3669 2 } 3670 1 3671 1 code = (NoBeautify ? PrintResponse(1) : PrintQResponse(1,0)); 3672 1 NoReformat = noReformatWas; 3673 1 return (code); 3674 1 } 3675 3676 /*********************************************************************** 3677 * execute a login request 3678 ***********************************************************************/ 3679 int DoLogin(inputLine) 3680 char *inputLine; 3681 { 3682 1 char encryptMe[MAXSTR]; /* string from nameserver */ 3683 1 char encrypted[MAXSTR]; /* string from ns, encrypted */ 3684 1 char *password; /* user's nameserver password */ 3685 1 int code; 3686 1 char scratch[MAXSTR]; 3687 1 3688 1 strcpy(scratch,inputLine); 3689 1 (void) strtok(scratch,DELIM); /* the login part of the command */ 3690 1 if (!strtok(0,DELIM)) /* check for an alias */ 3691 1 { 3692 2 printf("Enter nameserver alias: "); /* ask for missing alias */ 3693 2 fgets(scratch,sizeof(scratch),stdin); 3694 2 if (!*scratch) return(LR_ERROR); 3695 2 sprintf(inputLine,"login %s",scratch); 3696 2 } 3697 1 3698 1 qprintf(ToQI,"%s",inputLine); /* send login request */ 3699 2 qflush(ToQI); 3700 1 3701 1 for (;;) /* read the response */ 3702 1 { 3703 2 if (!GetGood(encryptMe, MAXSTR, FromQI)) 3704 2 { 3705 3 fprintf(stderr, "Whoops--the nameserver died.\n"); 3706 3 exit(1); 3707 3 } 3708 2 code = atoi(encryptMe); 3709 2 if (code != LR_LOGIN) /* intermediate or strange response */ 3710 2 fputs(encryptMe, stdout); 3711 2 if (code >= LR_OK) /* final response */ 3712 2 break; 3713 2 } 3714 1 3715 1 if (code == LR_LOGIN) 3716 1 { 3717 2 /* the nameserver has issued a challenge */ 3718 2 password = MyPassword ? MyPassword : 3719 2 getpass("Enter nameserver password: "); PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 16 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3720 2 crypt_start(password); 3721 2 3722 2 /* encrypt the challenge with the password */ 3723 2 encryptMe[strlen(encryptMe) - 1] = '\0'; /* strip linefeed */ 3724 2 encrypted[encryptit(encrypted, index(encryptMe, ':') + 1)] = '\0'; 3725 2 3726 2 /* send the encrypted text to qi */ 3727 2 qprintf(ToQI, "answer %s\n", encrypted); 3728 3 qflush(ToQI); 3729 2 3730 2 /* get the final response */ 3731 2 for (;;) 3732 2 { 3733 3 if (!GetGood(encryptMe, MAXSTR, FromQI)) 3734 3 { 3735 4 fprintf(stderr, "Whoops--the nameserver died.\n"); 3736 4 exit(1); 3737 4 } 3738 3 code = atoi(encryptMe); 3739 3 fputs(encryptMe, stdout); 3740 3 if (code >= LR_OK) /* final response */ 3741 3 break; 3742 3 } 3743 2 } 3744 1 3745 1 if (code == LR_OK) /* logged in */ 3746 1 { 3747 2 strcpy(MyAlias, index(encryptMe, ':') + 1); 3748 2 *index(MyAlias, ':') = '\0'; 3749 2 VetPassword(password); /* make sure password is reasonable */ 3750 2 } 3751 1 else 3752 1 *MyAlias = '\0'; 3753 1 return(code); 3754 1 } 3755 3756 /*********************************************************************** 3757 * execute a quit request 3758 ***********************************************************************/ 3759 int DoQuit(inputLine) 3760 char *inputLine; 3761 { 3762 1 DoOther("quit\n"); 3763 1 #ifdef VMS 3764 1 exit(SS$_NORMAL); 3765 1 #else 3766 X exit(LastCode=LR_MORE ? LastCode/100 : 0); 3767 1 #endif 3768 1 } 3769 3770 /*********************************************************************** 3771 * edit a field 3772 ***********************************************************************/ 3773 int DoEdit(inputLine) 3774 char *inputLine; 3775 { 3776 1 char *theField; PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 17 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3777 1 char *theAlias; 3778 1 char *theValue; 3779 1 int theCode=LR_OK; 3780 1 char confirm[10]; 3781 1 3782 1 (void) strtok(inputLine, DELIM); /* skip ``edit'' */ 3783 1 if (!(theField = strtok((char *) 0, DELIM))) 3784 1 { 3785 2 (void) DoCommand("help edit\n"); 3786 2 return(LR_ERROR); 3787 2 } 3788 1 3789 1 if (!(theAlias = strtok((char *) 0, DELIM))) 3790 1 theAlias = MyAlias; 3791 1 3792 1 if ((theValue = GetValue(theAlias, theField)) && EditValue(theValue)) 3793 1 { 3794 2 for (theCode=UpdateValue(theAlias,theField,theValue); 3795 2 400<=theCode && theCode<=499; 3796 2 theCode=UpdateValue(theAlias,theField,theValue)) 3797 2 { 3798 3 if (!isatty(0)) break; 3799 3 printf("Shall I try again [y/n]? "); 3800 3 fgets(confirm,sizeof(confirm),stdin); 3801 3 if (*confirm!='y' && *confirm!='Y') break; 3802 3 } 3803 2 if (theCode<300 && !strcmp(theField,"alias")) 3804 2 strcpy(MyAlias,theValue); 3805 2 } 3806 1 return(theCode); 3807 1 } 3808 3809 /*********************************************************************** 3810 * get the value of a field from the nameserver 3811 ***********************************************************************/ 3812 char *GetValue(theAlias, theField) 3813 char *theAlias; 3814 char *theField; 3815 { 3816 1 static char theValue[MAXVAL]; /* will hold the value */ 3817 1 char *vSpot; 3818 1 char scratch[MAXSTR]; 3819 1 int code; 3820 1 3821 1 if (!strcmp(theField, "password")) 3822 1 { 3823 2 puts("Use the ``password'' command, not edit."); 3824 2 return (NULL); 3825 2 } 3826 1 3827 1 /* do the query */ 3828 1 qprintf(ToQI, "query alias=%s return %s\n", theAlias, theField); 3829 2 qflush(ToQI); 3830 1 3831 1 *theValue = '\0'; 3832 1 3833 1 /* read qi response lines, concatenating the responses into one value */ PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 18 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3834 1 for (vSpot = theValue;; vSpot += strlen(vSpot)) 3835 1 { 3836 2 if (!GetGood(scratch, MAXSTR, FromQI)) 3837 2 { 3838 3 fprintf(stderr, "Ding-dong the server's dead!\n"); 3839 3 exit(0); 3840 3 } 3841 2 if ((code = atoi(scratch)) == -LR_OK) 3842 2 strcpy(vSpot, index(GetQValue(scratch), ':') + 2); /* part of value */ 3843 2 else 3844 2 if (code >= LR_OK) 3845 2 break; /* final response */ 3846 2 else 3847 2 fputs(scratch, stdout); /* ??? */ 3848 2 } 3849 1 3850 1 if (code != LR_OK) /* error */ 3851 1 fputs(scratch, stdout); 3852 1 3853 1 return (code == LR_OK ? theValue : NULL); 3854 1 } 3855 3856 /*********************************************************************** 3857 * Edit a value 3858 ***********************************************************************/ 3859 int EditValue(theValue) 3860 char *theValue; /* the value to edit */ 3861 { 3862 1 char *theFileName; /* name of temp file to use */ 3863 1 char *mktemp(); 3864 1 #ifdef VMS 3865 1 struct dsc$descriptor_s cli_input; 3866 1 char template[28], f1[28], f2[28], edit_command[64]; 3867 1 int istat; 3868 1 #else 3869 X char template[20]; 3870 1 #endif 3871 1 int fd; /* file descriptor for temp file */ 3872 1 static char newValue[MAXVAL]; /* new value */ 3873 1 char *editor; /* editor program to use */ 3874 1 int bytes; /* numnber of bytes in file */ 3875 1 register char *from, *to; 3876 1 int badChar; /* did we find a bad character? */ 3877 1 int junk; 3878 1 char scratch[80]; 3879 1 3880 1 /* put the value into a temp file */ 3881 1 #ifdef VMS 3882 1 strcpy(template, "SYS$SCRATCH:PHXXXXXX.TMP"); 3883 1 theFileName = mktemp(template); 3884 1 strcpy (f1, theFileName); 3885 1 strcpy (f2, theFileName); 3886 1 strcat (f1, ";1"); /* versions needed for delete function */ 3887 1 strcat (f2, ";2"); 3888 1 if ((fd = creat(theFileName, 0)) < 0) 3889 1 #else 3890 X strcpy(template, "/tmp/phXXXXXX"); PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 19 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3891 X theFileName = mktemp(template); 3892 X if ((fd = open(theFileName, O_RDWR | O_CREAT, 0777)) < 0) 3893 1 #endif 3894 1 { 3895 2 perror(theFileName); 3896 2 return (0); 3897 2 } 3898 1 3899 1 if (write(fd, theValue, strlen(theValue)) < 0) 3900 1 { 3901 2 perror(theFileName); 3902 2 (void) close(fd); 3903 2 return (0); 3904 2 } 3905 1 3906 1 (void) close(fd); 3907 1 3908 1 /* run an editor on the temp file */ 3909 1 #ifdef VMS 3910 1 if (!(editor = getenv("EDITOR"))) 3911 1 editor = "EDIT/TPU"; 3912 1 3913 1 strcpy(edit_command, editor); 3914 1 strcat(edit_command, " "); 3915 1 strcat(edit_command, theFileName); 3916 1 cli_input.dsc$w_length = strlen(edit_command); /* descriptor for spawn */ 3917 1 cli_input.dsc$a_pointer = edit_command; 3918 1 cli_input.dsc$b_class = DSC$K_CLASS_S; 3919 1 cli_input.dsc$b_dtype = DSC$K_DTYPE_T; 3920 1 3921 1 if( (istat = LIB$SPAWN(&cli_input)) != SS$_NORMAL ) 3922 1 { 3923 2 (void) delete (f1); 3924 2 exit(istat); 3925 2 } 3926 1 #else 3927 X if (!(editor = getenv("EDITOR"))) 3928 X #ifdef hpux 3929 X editor = "/usr/bin/vi"; 3930 X #else 3931 X editor = "/usr/ucb/vi"; 3932 X #endif 3933 X 3934 X if (fork()) 3935 X (void) wait((union wait *)&junk); 3936 X else 3937 X { 3938 X (void) execlp(editor, editor, theFileName, NULL); 3939 X fprintf(stderr,"Whoops! Failed to exec %s\n",editor); 3940 X exit(1); 3941 X } 3942 1 #endif 3943 1 3944 1 /* does the user want the value? */ 3945 1 if (Confirm) 3946 1 { 3947 2 do PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 20 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 3948 2 { 3949 3 printf("Change the value [y]? "); 3950 3 gets(scratch); 3951 3 } 3952 2 while (*scratch && !index("yYnN",*scratch)); 3953 2 } 3954 1 3955 1 /* read the value back out */ 3956 1 if ((fd = open(theFileName, 0)) < 0) 3957 1 { 3958 2 perror(theFileName); 3959 2 #ifdef VMS 3960 2 #else 3961 X (void) unlink(theFileName); 3962 2 #endif 3963 2 return (0); 3964 2 } 3965 1 3966 1 #ifdef VMS 3967 1 #else 3968 X (void) unlink(theFileName); 3969 1 #endif 3970 1 3971 1 if ((bytes = read(fd, newValue, MAXSTR - 1)) < 0) 3972 1 { 3973 2 perror(theFileName); 3974 2 (void) close(fd); 3975 2 #ifdef VMS 3976 2 (void) delete (f1); /* delete 1st temp file */ 3977 2 (void) delete (f2); /* delete 2nd temp file */ 3978 2 #endif 3979 2 return (0); 3980 2 } 3981 1 (void) close(fd); 3982 1 #ifdef VMS 3983 1 (void) delete (f1); /* delete 1st temp file */ 3984 1 (void) delete (f2); /* delete 2nd temp file */ 3985 1 #endif 3986 1 newValue[bytes] = 0; 3987 1 3988 1 /* did the value change? */ 3989 1 if (Confirm && *scratch && *scratch!='y' && *scratch!='Y' || 3990 1 !strcmp(newValue, theValue)) 3991 1 return (0); 3992 1 3993 1 /* copy new value into old, stripping bad characters */ 3994 1 badChar = 0; 3995 1 for (to = theValue, from = newValue; *from; from++) 3996 1 if (*from == '"') 3997 1 { 3998 2 *to++ = '\\'; 3999 2 *to++ = '"'; 4000 2 } 4001 1 else 4002 1 if (*from >= ' ' && *from <= '~') 4003 1 *to++ = *from; 4004 1 else PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 21 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4005 1 if (*from == '\t') 4006 1 { 4007 2 *to++ = '\\'; 4008 2 *to++ = 't'; 4009 2 } 4010 1 else 4011 1 if (*from == '\n') 4012 1 { 4013 2 if (*(from + 1)) /* skip terminating newline from vi */ 4014 2 { 4015 3 *to++ = '\\'; 4016 3 *to++ = 'n'; 4017 3 } 4018 2 } 4019 1 else 4020 1 badChar = 1; 4021 1 4022 1 *to = 0; 4023 1 4024 1 if (badChar) /* complain if we found bad characters */ 4025 1 { 4026 2 fputs("Illegal characters were found in your value.\n", stderr); 4027 2 fputs("Please use only printable characters, newlines, and tabs.\n", stderr); 4028 2 fputs("The offending characters were removed.\n", stderr); 4029 2 } 4030 1 4031 1 return (1); 4032 1 } 4033 4034 /*********************************************************************** 4035 * update a nameserver field with a new value 4036 ***********************************************************************/ 4037 int UpdateValue(theAlias, theField, theValue) 4038 char *theAlias; 4039 char *theField; 4040 char *theValue; 4041 { 4042 1 qprintf(ToQI, "change alias=%s make %s=\"%s\"\n", theAlias, theField, theValue); 4043 2 qflush(ToQI); 4044 1 4045 1 return(PrintResponse(0)); 4046 1 } 4047 /*********************************************************************** 4048 * print info on current user 4049 ***********************************************************************/ 4050 /*ARGSUSED*/ 4051 int DoMe(inputLine) 4052 char *inputLine; 4053 { 4054 1 if (!*MyAlias) 4055 1 { 4056 2 return(DoHelp("help me")); 4057 2 } 4058 1 4059 1 qprintf(ToQI, "query alias=%s return all\n", MyAlias); 4060 2 qflush(ToQI); 4061 1 PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 22 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4062 1 return(NoBeautify ? PrintResponse(0) : PrintQResponse(0,0)); 4063 1 } 4064 4065 /*********************************************************************** 4066 * set command-line switches 4067 ***********************************************************************/ 4068 int DoSwitch(inputLine) 4069 char *inputLine; 4070 { 4071 1 inputLine = strtok(inputLine,DELIM); 4072 1 if (!OptionLine(strtok(0,"\n"))) 4073 1 { 4074 2 printf("The following things can be changed with \"switch\":\n\n"); 4075 2 printf(" Paging is %s; use \"switch -%c\" to turn it %s.\n", 4076 2 NoPager ? "OFF" : "ON", 4077 2 NoPager ? 'M' : 'm', 4078 2 NoPager ? "on" : "off"); 4079 2 printf(" Email reformatting is %s; use \"switch -%c\" to turn it %s.\n", 4080 2 NoReformat ? "OFF" : "ON", 4081 2 NoReformat ? 'R' : 'r', 4082 2 NoReformat ? "on" : "off"); 4083 2 printf(" Query beautification is %s; use \"switch -%c\" to turn it %s.\n", 4084 2 NoBeautify ? "OFF" : "ON", 4085 2 NoBeautify ? 'B' : 'b', 4086 2 NoBeautify ? "on" : "off"); 4087 2 printf(" Label printing is %s; use \"switch -%c\" to turn it %s.\n", 4088 2 NoLabels ? "OFF" : "ON", 4089 2 NoLabels ? 'L' : 'l', 4090 2 NoLabels ? "on" : "off"); 4091 2 printf(" Edit confirmation is %s; use \"switch -%c\" to turn it %s.\n", 4092 2 Confirm ? "ON" : "OFF", 4093 2 Confirm ? 'c' : 'C', 4094 2 Confirm ? "off" : "on"); 4095 2 printf(" Default entry type is %s; use \"switch -%c%s\" to %s %s.\n", 4096 2 DefType ? DefType : "OFF", 4097 2 DefType ? 'T' : 't', 4098 2 DefType ? "" : " name-of-type", 4099 2 DefType ? "turn it" : "set it to", 4100 2 DefType ? "off" : "\"name-of-type\""); 4101 2 printf(" Default field list is %s; use \"switch -%c%s\" to %s to %s.\n", 4102 2 ReturnFields ? ReturnFields : "default", 4103 2 ReturnFields ? 'F' : 'f', 4104 2 ReturnFields ? "" : " field1,field2,... ", 4105 2 ReturnFields ? "revert" : "set it", 4106 2 ReturnFields ? "default" : "\"field1,field2,...\""); 4107 2 printf("\nThe following things cannot be changed with \"switch\":\n\n"); 4108 2 printf(" Connected to server %s at port %d\n", UseHost,UsePort); 4109 2 printf(" The .netrc file was %sread.\n", NoNetrc ? "not " : ""); 4110 2 } 4111 1 return(LR_OK); 4112 1 } 4113 4114 /*********************************************************************** 4115 * change a field value from the command line 4116 ***********************************************************************/ 4117 int DoMake(inputLine) 4118 char *inputLine; PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 23 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4119 { 4120 1 int theCode=LR_ERROR; 4121 1 4122 1 if (!*MyAlias) 4123 1 DoHelp("help make"); 4124 1 else 4125 1 { 4126 2 qprintf(ToQI,"change alias=%s %s",MyAlias,inputLine); 4127 3 qflush(ToQI); 4128 2 theCode = PrintResponse(0); 4129 2 } 4130 1 return(theCode); 4131 1 } 4132 4133 /*********************************************************************** 4134 * change password 4135 ***********************************************************************/ 4136 int DoPassword(inputLine) 4137 char *inputLine; 4138 { 4139 1 char password[80]; 4140 1 char *confirm; 4141 1 char *theAlias; 4142 1 int theCode=LR_ERROR; 4143 1 4144 1 if (!*MyAlias) 4145 1 { 4146 2 return(DoHelp("help password")); 4147 2 } 4148 1 4149 1 /* which alias to use? */ 4150 1 (void) strtok(inputLine, DELIM); 4151 1 if (!(theAlias = strtok((char *) 0, DELIM))) 4152 1 theAlias = MyAlias; 4153 1 4154 1 /* get the password */ 4155 1 strcpy(password, getpass("Enter new password: ")); 4156 1 if (!*password) return(LR_ERROR); 4157 1 confirm = getpass("Type it again: "); 4158 1 if (strcmp(confirm, password)) 4159 1 { 4160 2 fprintf(stderr, "Sorry--passwords didn't match.\n"); 4161 2 return(theCode); 4162 2 } 4163 1 VetPassword(confirm); /* complain if we don't like the password */ 4164 1 4165 1 /* encrypt and send the password */ 4166 1 password[encryptit(password, confirm)] = '\0'; 4167 1 qprintf(ToQI, "change alias=%s make password=%s\n", theAlias, password); 4168 2 qflush(ToQI); 4169 1 4170 1 /* see what the nameserver says */ 4171 1 if ((theCode=PrintResponse(0)) == LR_OK && !strcmp(theAlias,MyAlias)) 4172 1 crypt_start(confirm); 4173 1 return(theCode); 4174 1 } 4175 PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 24 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4176 /*********************************************************************** 4177 * log out the current user 4178 ***********************************************************************/ 4179 int DoLogout(inputLine) 4180 char *inputLine; 4181 { 4182 1 *MyAlias = '\0'; 4183 1 return(DoOther(inputLine)); 4184 1 } 4185 4186 /*********************************************************************** 4187 * complain about passwords we don't like 4188 ***********************************************************************/ 4189 void VetPassword(thePassword) 4190 char *thePassword; %CC-W-CONFLICTDECL, This declaration of "VetPassword" conflicts with a previous declaration of the same name. 4191 { 4192 1 if (strlen(thePassword) < 5 || /* too short */ 4193 1 AllDigits(thePassword)) /* digits only */ 4194 1 fputs("That is an insecure password; please change it.\n", stderr); 4195 1 } 4196 4197 /*********************************************************************** 4198 * is a string all digits 4199 ***********************************************************************/ 4200 int AllDigits(theString) 4201 register char *theString; 4202 { 4203 1 for (; *theString; theString++) 4204 1 if (!isdigit(*theString)) 4205 1 return (0); 4206 1 return (1); 4207 1 } 4208 4209 /*********************************************************************** 4210 * print the response to a query 4211 * this strips out all the nameserver reply codes. 4212 ***********************************************************************/ 4213 int PrintQResponse(reformatEmail,amHelping) 4214 int reformatEmail; 4215 int amHelping; 4216 { 4217 1 char theLine[MAXSTR]; 4218 1 int theCode=LR_ERROR; 4219 1 int currentPerson = 0; 4220 1 int thePerson; 4221 1 register char *cp; 4222 1 FILE *theOutput; 4223 1 char nickname[MAXSTR]; 4224 1 char alias[MAXSTR]; 4225 1 char email[MAXSTR]; 4226 1 int copiedEmail=0; 4227 1 4228 1 theOutput = OpenPager(1); 4229 1 PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 25 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4230 1 *alias = *email = *nickname = 0; /* haven't found an alias or nickname yet */ 4231 1 if (NoReformat) reformatEmail=0; 4232 1 /* get the response */ 4233 1 while (GetGood(theLine, MAXSTR, FromQI)) 4234 1 { 4235 2 theCode = atoi(theLine); 4236 2 if (theCode == LR_NUMRET) 4237 2 { 4238 3 #ifdef MACC 4239 X cp = strchr(theLine,':'); 4240 X if ( cp != 0) 4241 X fprintf(theOutput,"\n%s\n",cp+1); /* strchr returns pointer to : then add one */ 4242 3 #endif MACC 4243 3 } 4244 2 else 4245 2 if (theCode == -LR_OK || theCode == -LR_AINFO || theCode == -LR_ABSENT 4246 2 || theCode == -LR_ISCRYPT) 4247 2 { 4248 3 thePerson = atoi(index(theLine, ':') + 1); 4249 3 /* output a delimiter */ 4250 3 if (thePerson != currentPerson) 4251 3 { 4252 4 if (*alias && !*email) 4253 4 NotRegisteredLine(alias,theOutput); 4254 4 else if (*email) 4255 4 { 4256 5 EmailLine(email,alias,nickname); 4257 5 fputs(GetQValue(email),theOutput); 4258 5 *email = 0; 4259 5 } 4260 4 fputs("----------------------------------------\n", theOutput); 4261 4 currentPerson = thePerson; 4262 4 copiedEmail=0; 4263 4 } 4264 3 if (reformatEmail) 4265 3 { 4266 4 cp = GetQValue(theLine); 4267 4 while (*cp && *cp==' ') cp++; 4268 4 if (!strncmp("alias",cp,5)) 4269 4 { 4270 5 copiedEmail = 0; 4271 5 strcpy(alias,theLine); 4272 5 continue; 4273 5 } 4274 4 else if (!strncmp("email",cp,5)) 4275 4 { 4276 5 strcpy(email,theLine); 4277 5 copiedEmail = 1; 4278 5 continue; 4279 5 } 4280 4 else if (!strncmp("nickname",cp,8)) 4281 4 { 4282 5 copiedEmail = 0; 4283 5 strcpy(nickname,theLine); 4284 5 continue; 4285 5 } 4286 4 else if (*cp==':' && copiedEmail) PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 26 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4287 4 continue; 4288 4 else 4289 4 copiedEmail = 0; 4290 4 } 4291 3 /* output the line */ 4292 3 if (NoLabels && !amHelping) 4293 3 fputs(index(GetQValue(theLine),':')+2, theOutput); 4294 3 else 4295 3 fputs(GetQValue(theLine), theOutput); 4296 3 } 4297 2 else if (theCode != LR_OK) 4298 2 fputs(theLine, theOutput); /* error */ 4299 2 4300 2 if (theCode >= LR_OK) 4301 2 { 4302 3 if (*alias && !*email) 4303 3 NotRegisteredLine(alias,theOutput); 4304 3 else if (*email) 4305 3 { 4306 4 EmailLine(email,alias,nickname); 4307 4 /* output the line */ 4308 4 if (NoLabels && !amHelping) 4309 4 fputs(index(GetQValue(email),':')+2, theOutput); 4310 4 else 4311 4 fputs(GetQValue(email), theOutput); 4312 4 } 4313 3 break; 4314 3 } 4315 2 } 4316 1 4317 1 /* final "delimiter" */ 4318 1 if (currentPerson) 4319 1 fputs("----------------------------------------\n", theOutput); 4320 1 4321 1 #ifdef VMS 4322 1 #else 4323 X if (theOutput != stdout) 4324 X (void) pclose(theOutput); 4325 1 #endif 4326 1 4327 1 return(theCode); 4328 1 } 4329 4330 #ifndef NeXT 4331 /*********************************************************************** 4332 * break a string into tokens. this code is NOT lifted from sysV, but 4333 * was written from scratch. 4334 ***********************************************************************/ 4335 /* 4336 * function: strtok purpose: to break a string into tokens parameters: 4337 * s1 string to be tokenized or 0 (which will use last string) s2 delimiters 4338 * returns: pointer to first token. Puts a null after the token. returns 4339 * NULL if no tokens remain. 4340 */ 4341 char * 4342 strtok(s1, s2) 4343 char *s1, *s2; PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 27 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4344 { 4345 1 static char *old = 0; 4346 1 char *p1, *p2; 4347 1 4348 1 if (!(s1 || old)) 4349 1 return (NULL); 4350 1 p1 = (s1 ? s1 : old); 4351 1 while (*p1 && (index(s2, *p1) != NULL)) 4352 1 p1++; 4353 1 if (*p1) 4354 1 { 4355 2 p2 = p1; 4356 2 while (*p2 && (index(s2, *p2) == NULL)) 4357 2 p2++; 4358 2 if (*p2) 4359 2 { 4360 3 *p2 = '\0'; 4361 3 old = ++p2; 4362 3 } 4363 2 else 4364 2 old = 0; 4365 2 return (p1); 4366 2 } 4367 1 else 4368 1 return (NULL); 4369 1 } 4370 #endif 4371 #ifdef VMS 4372 /* setterm.c 4373 * 4374 * module in termlib 4375 * 4376 * contains routines to set terminal mode 4377 * 4378 * V1.0 19-jul-84 P. Schleifer Initial draft 4379 */ 4380 4381 setterm(characteristic, state) 4382 long *characteristic, *state; 4383 { 4384 1 int status; 4385 1 long efn; 4386 1 long new_state; 4387 1 short term_chan; 4388 1 struct char_buff mode; 4389 1 struct mode_iosb term_iosb; 4390 1 $DESCRIPTOR(term_desc, "TT:"); 4391 1 4392 1 /* get event flag */ 4393 1 status = lib$get_ef(&efn); 4394 1 if ( status != SS$_NORMAL ) return (status); 4395 1 4396 1 /* get channel to terminal */ 4397 1 status = sys$assign(&term_desc, &term_chan, 0, 0); 4398 1 if (status != SS$_NORMAL) return (status); 4399 1 4400 1 /* if characteristic is BROADCAST, ECHO, or TYPEAHEAD, state must be toggled */ PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 28 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4401 1 if (*characteristic == BROADCAST || *characteristic == ECHO || *characteristic == TYPEAHEAD) 4402 1 new_state = !(*state); 4403 1 else 4404 1 new_state = *state; 4405 1 4406 1 /* get current mode */ 4407 1 status = sys$qiow(efn, term_chan, IO$_SENSEMODE, &term_iosb, 0, 0, &mode, 12, 0, 0, 0, 0); 4408 1 if (status != SS$_NORMAL || term_iosb.stat != SS$_NORMAL) { sys$dassgn(term_chan); return (status); } 4409 1 4410 1 /* change characteristics buffer */ 4411 1 if (new_state == ON) 4412 1 mode.basic_char |= *characteristic; 4413 1 else 4414 1 mode.basic_char &= ~(*characteristic); 4415 1 4416 1 /* $ SET TERM/... and then deassign channel */ 4417 1 status = sys$qiow(efn, term_chan, IO$_SETMODE, &term_iosb, 0, 0, &mode, 12, 0, 0, 0, 0); 4418 1 4419 1 sys$dassgn(term_chan); 4420 1 lib$free_ef(&efn); 4421 1 4422 1 if (status != SS$_NORMAL) return (status); 4423 1 else return (term_iosb.stat); 4424 1 } 4425 4426 /*********************************************************************** 4427 * get password from stdin 4428 * 4429 * implement for VMS, since VAXCRTL lacks getpass() function. 4430 ***********************************************************************/ 4431 char *getpass(prompt) 4432 char *prompt; 4433 { 4434 1 4435 1 static char line [12]; 4436 1 static int echo = {ECHO}, off = {OFF}, on = {ON}; 4437 1 4438 1 printf(prompt); (void) fflush(stdout); /* prompt */ 4439 1 setterm(&echo, &off); 4440 1 gets(line); 4441 1 setterm(&echo, &on); 4442 1 puts(""); 4443 1 return(line); 4444 1 } 4445 #endif 4446 4447 /*********************************************************************** 4448 * use .netrc to login to nameserver, if possible 4449 ***********************************************************************/ 4450 void DoAutoLogin() 4451 { 4452 1 FILE *netrc; /* the .netrc file */ 4453 1 char pathName[1024];/* pathname of .netrc file */ 4454 1 struct stat theStat;/* permissions, etc. of .netrc file */ 4455 1 char key[80], val[80]; /* line from the .netrc file */ 4456 1 char *token; /* token (word) from the line from the .netrc file */ 4457 1 char *alias=NULL; /* the user's alias */ PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 29 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4458 1 char *pw=NULL; /* the user's password */ 4459 1 4460 1 /* 4461 1 * manufacture the pathname of the user's .netrc file 4462 1 */ 4463 1 sprintf(pathName,"%s/.netrc",getenv("HOME")); 4464 1 4465 1 /* 4466 1 * make sure its permissions are ok 4467 1 */ 4468 1 if (stat(pathName,&theStat)<0) 4469 1 return; 4470 1 if (theStat.st_mode & 077) 4471 1 return; /* refuse insecure files */ 4472 1 4473 1 /* 4474 1 * try to open it 4475 1 */ 4476 1 if (!(netrc=fopen(pathName,"r"))) 4477 1 return; 4478 1 4479 1 /* 4480 1 * look for a ``machine'' named ``ph'' 4481 1 */ 4482 1 while (2==fscanf(netrc,"%s %s",key,val)) 4483 1 { 4484 2 if (!strcmp(key,"machine") && !strcmp(val,CLIENT)) 4485 2 { 4486 3 /* 4487 3 * found an entry for ph. look now for other items 4488 3 */ 4489 3 while (2==fscanf(netrc,"%s %s",key,val)) 4490 3 { 4491 4 if (!strcmp(key,"machine")) /* new machine */ 4492 4 { 4493 5 if (alias) {free(alias);alias=NULL;} 4494 5 if (pw) {free(pw);pw=NULL;} 4495 5 break; 4496 5 } 4497 4 else if (!strcmp(key,"login")) 4498 4 alias=strcpy(malloc((unsigned)strlen(val)+1),val); 4499 4 else if (!strcmp(key,"password")) 4500 4 pw=strcpy(malloc((unsigned)strlen(val)+1),val); 4501 4 else if (!strcmp(key,"macdef")) SkipMacdef(netrc); 4502 4 4503 4 if (alias && pw && TryLogin(alias,pw)) 4504 4 goto done; 4505 4 } 4506 3 } 4507 2 else if (!strcmp(key,"macdef")) SkipMacdef(netrc); 4508 2 } 4509 1 4510 1 done: 4511 1 if (alias) free(alias); 4512 1 if (pw) free(pw); 4513 1 return; 4514 1 } PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 30 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4515 4516 /*********************************************************************** 4517 * skip a macdef in the .netrc file 4518 ***********************************************************************/ 4519 void SkipMacdef(netrc) 4520 FILE *netrc; 4521 { 4522 1 int c, wasNl; 4523 1 4524 1 for (wasNl=0;(c=getc(netrc))!=EOF;wasNl=(c=='\n')) 4525 1 if (wasNl && c=='\n') break; 4526 1 } 4527 4528 /*********************************************************************** 4529 * try a login alias and password 4530 ***********************************************************************/ 4531 int TryLogin(alias,password) 4532 char *alias; 4533 char *password; 4534 { 4535 1 char loginLine[80]; 4536 1 int success; 4537 1 4538 1 /* 4539 1 * construct a login line 4540 1 */ 4541 1 sprintf(loginLine,"login %s\n",alias); 4542 1 4543 1 /* 4544 1 * set our password 4545 1 */ 4546 1 MyPassword=password; 4547 1 4548 1 /* 4549 1 * try the login 4550 1 */ 4551 1 success = DoLogin(loginLine,0); 4552 1 4553 1 /* 4554 1 * reset our password 4555 1 */ 4556 1 MyPassword = NULL; 4557 1 while (*password) *password++ = 'x'; 4558 1 4559 1 /* 4560 1 * return our success (or failure) 4561 1 */ 4562 1 return(success); 4563 1 } 4564 4565 4566 /*********************************************************************** 4567 * execute a help request 4568 ***********************************************************************/ 4569 int DoHelp(inputLine) 4570 char *inputLine; 4571 { PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 31 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4572 1 char scratch[256]; 4573 1 char *token; 4574 1 4575 1 strcpy(scratch,inputLine); 4576 1 token = strtok(scratch+4,DELIM); /* the word after help */ 4577 1 if (token && !strcmp(token,"native")) /* looking for native help */ 4578 1 strcpy(scratch,inputLine); /* leave the command alone */ 4579 1 else 4580 1 sprintf(scratch,"help %s %s",CLIENT,inputLine+4); /* insert identifier */ 4581 1 4582 1 qprintf(ToQI,"%s",scratch); /* send command */ 4583 2 qflush(ToQI); 4584 1 return (NoBeautify ? PrintResponse(0) : PrintQResponse(0,1)); 4585 1 } 4586 4587 /************************************************************************ 4588 * reformat an email line to include an alias address 4589 * this is kind of a hack since we're working on an already-formatted line 4590 ************************************************************************/ 4591 void EmailLine(email,alias,nickname) 4592 char *email; 4593 char *alias; 4594 char *nickname; 4595 { 4596 1 char scratch[MAXSTR]; 4597 1 char *emSpot; /* beginning of email account */ 4598 1 char *alSpot; /* beginning of nameserver alias */ 4599 1 char *niSpot; /* beginning of nickname field */ 4600 1 4601 1 if (*nickname) 4602 1 { 4603 2 emSpot = index(GetQValue(email), ':') + 2; 4604 2 niSpot = index(GetQValue(nickname), ':') + 2; 4605 2 *index(niSpot,'\n') = 0; 4606 2 *index(emSpot,'\n') = 0; 4607 2 /* 4608 2 * overwrite the email label 4609 2 */ 4610 2 strcpy(niSpot-2-strlen("email to"),"email to"); 4611 2 niSpot[-2] = ':'; /* strcpy clobbered the colon; repair */ 4612 2 sprintf(scratch,"@%s\n",MAILDOMAIN); 4613 2 strcat(nickname,scratch); 4614 2 strcpy(email,nickname); /* leave it in the "email" line */ 4615 2 *nickname = 0; /* we're done with the alias */ 4616 2 } 4617 1 else if (*alias) 4618 1 { 4619 2 emSpot = index(GetQValue(email), ':') + 2; 4620 2 alSpot = index(GetQValue(alias), ':') + 2; 4621 2 *index(alSpot,'\n') = 0; 4622 2 *index(emSpot,'\n') = 0; 4623 2 /* 4624 2 * overwrite the email label 4625 2 */ 4626 2 strcpy(alSpot-2-strlen("email to"),"email to"); 4627 2 alSpot[-2] = ':'; /* strcpy clobbered the colon; repair */ 4628 2 sprintf(scratch,"@%s\n",MAILDOMAIN); PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 32 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4629 2 strcat(alias,scratch); 4630 2 strcpy(email,alias); /* leave it in the "email" line */ 4631 2 *alias = 0; /* we're done with the alias */ 4632 2 } 4633 1 } 4634 4635 /************************************************************************ 4636 * put out a ``not registered'' line with alias 4637 ************************************************************************/ 4638 void NotRegisteredLine(alias,theOutput) 4639 char *alias; 4640 FILE *theOutput; 4641 { 4642 1 char scratch[MAXSTR]; 4643 1 register char *cp; 4644 1 4645 1 strcpy(scratch,alias); 4646 1 cp = index(GetQValue(scratch),':'); 4647 1 strcpy(cp-8,"email to:"); 4648 1 strcpy(cp+1," (no address registered)\n"); 4649 1 /* output the line */ 4650 1 if (NoLabels) 4651 1 fputs(index(GetQValue(scratch),':')+2, theOutput); 4652 1 else 4653 1 fputs(GetQValue(scratch), theOutput); 4654 1 *alias = 0; /* done with alias */ 4655 1 } 4656 4657 /************************************************************************ 4658 * process a set of options 4659 ************************************************************************/ 4660 int ProcessOptions(argc,argv) 4661 int argc; 4662 char **argv; 4663 { 4664 1 int count = 0; 4665 1 /* 4666 1 * options processing 4667 1 */ 4668 1 for (;argc && **argv=='-'; argc--,argv++,count++) 4669 1 { 4670 2 for ((*argv)++; **argv; (*argv)++) 4671 2 { 4672 3 switch(**argv) 4673 3 { 4674 4 case 'r': NoReformat = 1; break; 4675 4 case 'R': NoReformat = 0; break; 4676 4 case 'n': NoNetrc = 1; break; 4677 4 case 'N': NoNetrc = 0; break; 4678 4 case 'm': NoPager = 1; break; 4679 4 case 'M': NoPager = 0; break; 4680 4 case 'b': NoBeautify = 1; break; 4681 4 case 'B': NoBeautify = 0; break; 4682 4 case 'l': NoLabels = 1; break; 4683 4 case 'L': NoLabels = 0; break; 4684 4 case 'C': Confirm = 1; break; 4685 4 case 'c': Confirm = 0; break; PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 33 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4686 4 case 's': 4687 4 if (argv[0][1]) 4688 4 { 4689 5 if (UseHost) free(UseHost); 4690 5 UseHost = makestr(*argv + 1); 4691 5 goto whilebottom; 4692 5 } 4693 4 else if (argc>1) 4694 4 { 4695 5 if (UseHost) free(UseHost); 4696 5 UseHost = makestr(argv[1]); 4697 5 argc--,argv++,count++; 4698 5 goto whilebottom; 4699 5 } 4700 4 else 4701 4 fprintf(stderr,"-%c option given without server hostname.\n", **argv); 4702 4 break; 4703 4 case 't': 4704 4 if (argv[0][1]) 4705 4 { 4706 5 if (DefType) free(DefType); 4707 5 DefType = makestr(*argv + 1); 4708 5 goto whilebottom; 4709 5 } 4710 4 else if (argc>1) 4711 4 { 4712 5 if (DefType) free(DefType); 4713 5 DefType = makestr(argv[1]); 4714 5 argc--,argv++,count++; 4715 5 goto whilebottom; 4716 5 } 4717 4 else 4718 4 fprintf(stderr,"-%t option given without entry type.\n", **argv); 4719 4 break; 4720 4 case 'f': 4721 4 if (argv[0][1]) 4722 4 { 4723 5 if (ReturnFields) free(ReturnFields); 4724 5 ReturnFields = makestr(*argv + 1); 4725 5 goto whilebottom; 4726 5 } 4727 4 else if (argc>1) 4728 4 { 4729 5 if (ReturnFields) free(ReturnFields); 4730 5 ReturnFields = makestr(argv[1]); 4731 5 argc--,argv++,count++; 4732 5 goto whilebottom; 4733 5 } 4734 4 else 4735 4 fprintf(stderr,"-%t option given without field list.\n", **argv); 4736 4 break; 4737 4 case 'F': 4738 4 if (ReturnFields) free(ReturnFields); 4739 4 ReturnFields = 0; 4740 4 break; 4741 4 case 'T': 4742 4 if (DefType) free(DefType); PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 34 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4743 4 DefType = 0; 4744 4 break; 4745 4 case 'p': 4746 4 if (isdigit(argv[0][1])) 4747 4 { 4748 5 UsePort = htons(atoi(*argv + 1)); 4749 5 goto whilebottom; 4750 5 } 4751 4 else if (argc>1 && isdigit(*argv[1])) 4752 4 { 4753 5 UsePort = htons(atoi(argv[1])); 4754 5 argc--,argv++,count++; 4755 5 goto whilebottom; 4756 5 } 4757 4 else 4758 4 fprintf(stderr,"-%c option given without port number.\n", **argv); 4759 4 break; 4760 4 default: 4761 4 fprintf(stderr,"Unknown option: -%c.\n",**argv); 4762 4 } 4763 3 } 4764 2 whilebottom:; 4765 2 } 4766 1 return(count); 4767 1 } 4768 4769 /************************************************************************ 4770 * Process a lineful of options 4771 ************************************************************************/ 4772 OptionLine(line) 4773 char *line; 4774 { 4775 1 int argc; 4776 1 char *argv[MAXARGS]; 4777 1 char *token; 4778 1 4779 1 if (!line || !*line) return; 4780 1 4781 1 for (argc=0,token=strtok(line,DELIM);token;argc++,token=strtok(0,DELIM)) 4782 1 argv[argc] = token; 4783 1 argv[argc] = 0; 4784 1 4785 1 return(ProcessOptions(argc,argv)); 4786 1 } 4787 4788 /************************************************************************ 4789 * OpenPager - open the user's chosen pager 4790 ************************************************************************/ 4791 FILE *OpenPager(doPaging) 4792 int doPaging; 4793 { 4794 1 char *thePager; 4795 1 FILE *theOutput; 4796 1 4797 1 #ifdef VMS 4798 1 return(stdout); /* simpler to skip paging for right now */ 4799 1 #else PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 35 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4800 X if (NoPager || doPaging!=1) 4801 X return(stdout); 4802 X else 4803 X { 4804 X if ((thePager = getenv("PAGER")) == NULL) 4805 X #ifdef hpux 4806 X thePager = "/usr/bin/more"; 4807 X #else 4808 X thePager = "/usr/ucb/more"; 4809 X #endif 4810 X if ((theOutput = popen(thePager, "w")) == NULL) 4811 X theOutput = stdout; 4812 X return(theOutput); 4813 X } 4814 1 #endif 4815 1 } 4816 4817 /************************************************************************ 4818 * makestr - make a copy of a string in malloc-space 4819 ************************************************************************/ 4820 char *makestr(str) 4821 char *str; 4822 { 4823 1 char *copy; 4824 1 int len; 4825 1 4826 1 len = strlen(str); 4827 1 if (copy=malloc(len+1)) 4828 1 strcpy(copy,str); 4829 1 return(copy); 4830 1 } 4831 4832 /************************************************************************ 4833 * issub - is one string a substring of another? 4834 ************************************************************************/ 4835 char *issub(string, sub) 4836 char *string; 4837 char *sub; 4838 { 4839 1 int len; 4840 1 4841 1 len = strlen(sub); 4842 1 for (; *string; string++) 4843 1 if (!strncmp(string, sub, len)) 4844 1 return (string); 4845 1 return (0); 4846 1 } 4847 4848 /*********************************************************************** 4849 * EnvOptions - grab some options from the environment 4850 ***********************************************************************/ 4851 void EnvOptions(name) 4852 char *name; 4853 { 4854 1 char buffer[80]; 4855 1 register char *np,*bp; 4856 1 PH 23-SEP-1993 13:35:39 VAX C V3.2-044 Page 36 V1.0 23-SEP-1993 13:33:19 X$SRC:[CSO.PH]PH.C;2 (1) 4857 1 for (np=name,bp=buffer; *np; np++,bp++) 4858 1 *bp = islower(*np) ? toupper(*np) : *np; 4859 1 *bp = 0; 4860 1 OptionLine(getenv(buffer)); 4861 1 } %CC-I-NOBJECT, No object file produced. Command Line ------------ CC/DEBUG/NOOP/DEFINE=(HOST="psulias.psu.edu",FALLBACKADDR=0X807658C8,NSSERVICE="CSO",FALLBACKPORT=105,ADMIN="jlw@psulias.psu.edu",MA ILDOMAIN="psulias.psu.edu",CLIENT="ph") PH/DEBUG/LIST .