1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
|
/*
* Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory
*/
#include <xpap.h>
extern char *optarg;
extern int optind;
#ifdef ANSI_FUNC
void
usage (char *s)
#else
void usage(s)
char *s;
#endif
{
fprintf(stderr, "\n");
fprintf(stderr, "usage:\n");
fprintf(stderr, " <data> | %s [-h] [-i nsinet] [-m method] [-n] [-p] [-s] [-t sval,lval] [-u users] <tmpl|host:port> [paramlist]\n", s);
fprintf(stderr, "\n");
fprintf(stderr, "switches:\n");
fprintf(stderr, "\t-h\tprint this message\n");
fprintf(stderr, "\t-i\toverride XPA_NSINET environment variable\n");
fprintf(stderr, "\t-m\toverride XPA_METHOD environment variable\n");
fprintf(stderr, "\t-n\tdon't wait for message after server completes\n");
fprintf(stderr, "\t-p\tdon't read (or send) buf data from stdin\n");
fprintf(stderr, "\t-s\tserver mode\n");
fprintf(stderr, "\t-t \toverride XPA_[SHORT,LONG]_TIMEOUT environment variables\n");
fprintf(stderr, "\t-u\toverride XPA_NSUSERS environment variable\n");
fprintf(stderr, "\t-v\tverify message to stdout\n");
fprintf(stderr, "\t--version display version and exit\n");
fprintf(stderr, "\n");
fprintf(stderr, "Data will be sent to access points matching the template or host:port.\n");
fprintf(stderr, "Templates are of the form [class:]name. Wildcards *,?,[] are accepted.\n");
fprintf(stderr, "A set of qualifying parameters can be appended.\n");
fprintf(stderr, "\n");
fprintf(stderr, "examples:\n");
fprintf(stderr, "\tcsh> xpaset ds9 fits foo.fits < foo.fits\n");
fprintf(stderr, "\tcsh> echo \"stop\" | xpaset bynars:28571\n");
fprintf(stderr, "\n(version: %s)\n", XPA_VERSION);
exit(1);
}
#ifdef ANSI_FUNC
int
main (int argc, char **argv)
#else
int
main(argc, argv)
int argc;
char **argv;
#endif
{
int i;
int c;
int got;
int lp;
int errcode=0;
int server=0;
int hmax=XPA_MAXHOSTS;
char *paramlist=NULL;
char *xtemplate=NULL;
char lbuf[SZ_LINE];
char tbuf[SZ_LINE];
char mode[SZ_LINE];
char cmd[SZ_LINE];
char *s;
char **errs=NULL;
char **names=NULL;
int fd;
XPA xpa=NULL;
/* display version and exit, if necessary */
if( (argc == 2) && !strcmp(argv[1], "--version") ){
fprintf(stderr, "%s\n", XPA_VERSION);
exit(0);
}
/* make sure we have enough arguments */
if( argc < 2 )
usage(argv[0]);
/* start with no mode flag */
*mode = '\0';
/* read from stdin */
fd = fileno(stdin);
/* we want the args in the same order in which they arrived, and
gnu getopt sometimes changes things without this */
putenv("POSIXLY_CORRECT=true");
/* process switch arguments */
while ((c = getopt(argc, argv, "hi:m:npst:u:vwW")) != -1){
switch(c){
case 'h':
usage(argv[0]);
case 'i':
snprintf(cmd, SZ_LINE, "XPA_NSINET=%s", optarg);
putenv(xstrdup(cmd));
break;
case 'm':
snprintf(cmd, SZ_LINE, "XPA_METHOD=%s", optarg);
putenv(xstrdup(cmd));
break;
case 'n':
if( *mode != '\0' )
strcat(mode, ",");
strcat(mode, "ack=false");
break;
case 'p':
fd = -1;
break;
case 's':
server = 1;
if( xpa == NULL )
xpa = XPAOpen(NULL);
break;
case 't':
{
int xip=0;
char xbuf[SZ_LINE];
newdtable(",;");
if( word(optarg, xbuf, &xip) && *xbuf && (*xbuf != '*') ){
snprintf(cmd, SZ_LINE, "XPA_SHORT_TIMEOUT=%s", xbuf);
putenv(xstrdup(cmd));
}
if( word(optarg, xbuf, &xip) && *xbuf && (*xbuf != '*') ){
snprintf(cmd, SZ_LINE, "XPA_LONG_TIMEOUT=%s", xbuf);
putenv(xstrdup(cmd));
}
freedtable();
}
break;
case 'u':
snprintf(cmd, SZ_LINE, "XPA_NSUSERS=%s", optarg);
putenv(xstrdup(cmd));
break;
case 'v':
if( *mode != '\0' )
strcat(mode, ",");
strcat(mode, "verify=true");
break;
/* for backward compatibility with 1.0 */
case 'w':
case 'W':
break;
}
}
/* no explicit host:port specified, so we should have a name */
if( optind >= argc ){
/* in server mode, we can skip the host on the command line */
if( !server )
usage(argv[0]);
}
else{
xtemplate = xstrdup(argv[optind]);
optind++;
}
/* make the paramlist */
paramlist = XPAArgvParamlist(argc, argv, optind);
/* init variables for names and ports */
if( (s=(char *)getenv("XPA_MAXHOSTS")) != NULL )
hmax = atoi(s);
names = (char **)xcalloc(hmax, sizeof(char *));
errs = (char **)xcalloc(hmax, sizeof(char *));
again:
/* if we are in server mode, we might have to read a line from stdin
to grab the template and paramlist */
if( server && (xtemplate==NULL) ){
/* read description of template and paramlist */
if( fgets(lbuf, SZ_LINE, stdin) == NULL )
exit(errcode);
if( (*lbuf == '#') || (*lbuf == '\n') )
goto again;
lp = 0;
if( word(lbuf, tbuf, &lp) && !strcmp(tbuf, "xpaset") &&
word(lbuf, tbuf, &lp) ){
xtemplate = xstrdup(tbuf);
paramlist = xstrdup(&(lbuf[lp]));
nowhite(paramlist, paramlist);
}
else{
fprintf(stderr, "XPA$ERROR invalid command: %s", lbuf);
exit(++errcode);
}
}
/* process xpa requests */
got = XPASetFd(xpa, xtemplate, paramlist, mode, fd, names, errs, hmax);
/* process errors */
if( got == 0 ){
fprintf(stderr, "XPA$ERROR no 'xpaset' access points match template: %s\n",
xtemplate);
errcode++;
}
else{
/* display errors and free up strings */
for(i=0; i<got; i++){
if( errs[i] != NULL ){
fprintf(stderr, "%s", errs[i]);
xfree(errs[i]);
errcode++;
}
if( names[i] != NULL )
xfree(names[i]);
}
}
/* free the paramlist */
if( paramlist!= NULL ){
xfree(paramlist);
paramlist = NULL;
}
/* and the template */
if( xtemplate != NULL ){
xfree(xtemplate);
xtemplate = NULL;
}
/* if we are in server mode, go back for more */
if( server )
goto again;
/* else exit */
else{
/* clean up */
if( errs ) xfree(errs);
if( names ) xfree(names);
XPACleanup();
exit(errcode);
}
return(0);
}
|