1/* 2 * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) 3 * Copyright (c) 1990,1993 Regents of The University of Michigan. 4 * All Rights Reserved. See COPYRIGHT. 5 * 6 * modified from main.c. this handles afp options. 7 */ 8 9#ifdef HAVE_CONFIG_H 10#include "config.h" 11#endif /* HAVE_CONFIG_H */ 12 13#include <stdio.h> 14#include <stdlib.h> 15#include <string.h> 16#include <ctype.h> 17#include <unistd.h> 18#include <sys/param.h> 19#include <sys/socket.h> 20#include <atalk/logger.h> 21 22#include <netinet/in.h> 23#include <arpa/inet.h> 24 25#ifdef HAVE_NETDB_H 26#include <netdb.h> 27#endif /* HAVE_NETDB_H */ 28 29#ifdef ADMIN_GRP 30#include <grp.h> 31#include <sys/types.h> 32#endif /* ADMIN_GRP */ 33 34#include <atalk/paths.h> 35#include <atalk/util.h> 36#include <atalk/compat.h> 37#include <atalk/globals.h> 38#include <atalk/fce_api.h> 39 40#include "status.h" 41#include "auth.h" 42#include "dircache.h" 43 44#ifndef MIN 45#define MIN(a, b) ((a) < (b) ? (a) : (b)) 46#endif /* MIN */ 47 48/* FIXME CNID */ 49const char *Cnid_srv = "localhost"; 50const char *Cnid_port = "4700"; 51 52#define OPTIONS "dn:f:s:uc:g:P:ptDS:TL:F:U:hIvVm:" 53#define LENGTH 512 54 55/* return an option. this uses an internal array, so it's necessary 56 * to duplicate it if you want to hold it for long. this is probably 57 * non-optimal. */ 58static char *getoption(char *buf, const char *option) 59{ 60 static char string[LENGTH + 1]; 61 char *end; 62 int len; 63 64 if (option && (buf = strstr(buf, option))) 65 buf = strpbrk(buf, " \t"); 66 67 while (buf && isspace(*buf)) 68 buf++; 69 70 if (!buf) 71 return NULL; 72 73 /* search for any quoted stuff */ 74 if (*buf == '"' && (end = strchr(buf + 1, '"'))) { 75 buf++; 76 len = MIN(end - buf, LENGTH); 77 } else if ((end = strpbrk(buf, " \t\n"))) /* option or eoln */ 78 len = MIN(end - buf, LENGTH); 79 else 80 len = MIN(strlen(buf), LENGTH); 81 82 strncpy(string, buf, len); 83 string[len] = '\0'; 84 return string; 85} 86 87/* get rid of any allocated afp_option buffers. */ 88void afp_options_free(struct afp_options *opt, 89 const struct afp_options *save) 90{ 91 if (opt->defaultvol.name && (opt->defaultvol.name != save->defaultvol.name)) 92 free(opt->defaultvol.name); 93 if (opt->defaultvol.full_name && (opt->defaultvol.full_name != save->defaultvol.full_name)) 94 free(opt->defaultvol.full_name); 95 96 if (opt->systemvol.name && (opt->systemvol.name != save->systemvol.name)) 97 free(opt->systemvol.name); 98 if (opt->systemvol.full_name && (opt->systemvol.full_name != save->systemvol.full_name)) 99 free(opt->systemvol.full_name); 100 101 if (opt->uservol.name && (opt->uservol.name != save->uservol.name)) 102 free(opt->uservol.name); 103 if (opt->uservol.full_name && (opt->uservol.full_name != save->uservol.full_name)) 104 free(opt->uservol.full_name); 105 106 if (opt->loginmesg && (opt->loginmesg != save->loginmesg)) 107 free(opt->loginmesg); 108 if (opt->guest && (opt->guest != save->guest)) 109 free(opt->guest); 110 if (opt->server && (opt->server != save->server)) 111 free(opt->server); 112 if (opt->ipaddr && (opt->ipaddr != save->ipaddr)) 113 free(opt->ipaddr); 114 if (opt->port && (opt->port != save->port)) 115 free(opt->port); 116 if (opt->fqdn && (opt->fqdn != save->fqdn)) 117 free(opt->fqdn); 118 if (opt->uampath && (opt->uampath != save->uampath)) 119 free(opt->uampath); 120 if (opt->uamlist && (opt->uamlist != save->uamlist)) 121 free(opt->uamlist); 122 if (opt->passwdfile && (opt->passwdfile != save->passwdfile)) 123 free(opt->passwdfile); 124 if (opt->signatureopt && (opt->signatureopt != save->signatureopt)) 125 free(opt->signatureopt); 126 if (opt->k5service && (opt->k5service != save->k5service)) 127 free(opt->k5service); 128 if (opt->k5realm && (opt->k5realm != save->k5realm)) 129 free(opt->k5realm); 130 if (opt->k5keytab && (opt->k5keytab != save->k5keytab)) 131 free(opt->k5keytab); 132 if (opt->unixcodepage && (opt->unixcodepage != save->unixcodepage)) 133 free(opt->unixcodepage); 134 if (opt->maccodepage && (opt->maccodepage != save->maccodepage)) 135 free(opt->maccodepage); 136 137 if (opt->ntdomain && (opt->ntdomain != save->ntdomain)) 138 free(opt->ntdomain); 139 if (opt->ntseparator && (opt->ntseparator != save->ntseparator)) 140 free(opt->ntseparator); 141 if (opt->logconfig && (opt->logconfig != save->logconfig)) 142 free(opt->logconfig); 143 if (opt->mimicmodel && (opt->mimicmodel != save->mimicmodel)) 144 free(opt->mimicmodel); 145} 146 147/* initialize options */ 148void afp_options_init(struct afp_options *options) 149{ 150 memset(options, 0, sizeof(struct afp_options)); 151 options->connections = 20; 152 options->pidfile = _PATH_AFPDLOCK; 153 options->defaultvol.name = _PATH_AFPDDEFVOL; 154 options->systemvol.name = _PATH_AFPDSYSVOL; 155 options->configfile = _PATH_AFPDCONF; 156 options->sigconffile = _PATH_AFPDSIGCONF; 157 options->uuidconf = _PATH_AFPDUUIDCONF; 158 options->uampath = _PATH_AFPDUAMPATH; 159 options->uamlist = "uams_dhx.so,uams_dhx2.so"; 160 options->guest = "nobody"; 161 options->loginmesg = ""; 162 options->transports = AFPTRANS_TCP; /* TCP only */ 163 options->passwdfile = _PATH_AFPDPWFILE; 164 options->tickleval = 30; 165 options->timeout = 4; /* 4 tickles = 2 minutes */ 166 options->sleep = 10 * 60 * 2; /* 10 h in 30 seconds tick */ 167 options->disconnected = 10 * 60 * 2; /* 10 h in 30 seconds tick */ 168 options->server_notif = 1; 169 options->authprintdir = NULL; 170 options->signatureopt = "auto"; 171 options->umask = 0; 172#ifdef ADMIN_GRP 173 options->admingid = 0; 174#endif /* ADMIN_GRP */ 175 options->k5service = NULL; 176 options->k5realm = NULL; 177 options->k5keytab = NULL; 178 options->unixcharset = CH_UNIX; 179 options->unixcodepage = "LOCALE"; 180 options->maccharset = CH_MAC; 181 options->maccodepage = "MAC_ROMAN"; 182 options->volnamelen = 80; /* spec: 255, 10.1: 73, 10.4/10.5: 80 */ 183 options->ntdomain = NULL; 184 options->ntseparator = NULL; 185#ifdef USE_SRVLOC 186 /* don't advertize slp by default */ 187 options->flags |= OPTION_NOSLP; 188#endif 189 options->dircachesize = DEFAULT_MAX_DIRCACHE_SIZE; 190 options->flags |= OPTION_ACL2MACCESS; 191 options->flags |= OPTION_UUID; 192 options->tcp_sndbuf = 0; /* 0 means don't change OS default */ 193 options->tcp_rcvbuf = 0; /* 0 means don't change OS default */ 194 options->dsireadbuf = 12; 195 options->mimicmodel = NULL; 196} 197 198/* parse an afpd.conf line. i'm doing it this way because it's 199 * easy. it is, however, massively hokey. sample afpd.conf: 200 * server:AFPServer@zone -loginmesg "blah blah blah" -nodsi 201 * "private machine"@zone2 -noguest -port 11012 202 * server2 -nocleartxt -nodsi 203 * 204 * NOTE: this ignores unknown options 205 */ 206int afp_options_parseline(char *buf, struct afp_options *options) 207{ 208 char *c, *opt; 209 210 /* handle server */ 211 if (*buf != '-' && (c = getoption(buf, NULL)) && (opt = strdup(c))) 212 options->server = opt; 213 214 /* parse toggles */ 215 if (strstr(buf, " -nodebug")) 216 options->flags &= ~OPTION_DEBUG; 217#ifdef USE_SRVLOC 218 if (strstr(buf, " -slp")) 219 options->flags &= ~OPTION_NOSLP; 220#endif 221#ifdef USE_ZEROCONF 222 if (strstr(buf, " -nozeroconf")) 223 options->flags |= OPTION_NOZEROCONF; 224#endif 225 if (strstr(buf, " -nouservolfirst")) 226 options->flags &= ~OPTION_USERVOLFIRST; 227 if (strstr(buf, " -uservolfirst")) 228 options->flags |= OPTION_USERVOLFIRST; 229 if (strstr(buf, " -nouservol")) 230 options->flags |= OPTION_NOUSERVOL; 231 if (strstr(buf, " -uservol")) 232 options->flags &= ~OPTION_NOUSERVOL; 233 if (strstr(buf, " -proxy")) 234 options->flags |= OPTION_PROXY; 235 if (strstr(buf, " -noicon")) 236 options->flags &= ~OPTION_CUSTOMICON; 237 if (strstr(buf, " -icon")) 238 options->flags |= OPTION_CUSTOMICON; 239 if (strstr(buf, " -advertise_ssh")) 240 options->flags |= OPTION_ANNOUNCESSH; 241 if (strstr(buf, " -noacl2maccess")) 242 options->flags &= ~OPTION_ACL2MACCESS; 243 244 /* passwd bits */ 245 if (strstr(buf, " -nosavepassword")) 246 options->passwdbits |= PASSWD_NOSAVE; 247 if (strstr(buf, " -savepassword")) 248 options->passwdbits &= ~PASSWD_NOSAVE; 249 if (strstr(buf, " -nosetpassword")) 250 options->passwdbits &= ~PASSWD_SET; 251 if (strstr(buf, " -setpassword")) 252 options->passwdbits |= PASSWD_SET; 253 254 /* transports */ 255 if (strstr(buf, " -transall")) 256 options->transports = AFPTRANS_ALL; 257 if (strstr(buf, " -notransall")) 258 options->transports = AFPTRANS_NONE; 259 if (strstr(buf, " -tcp")) 260 options->transports |= AFPTRANS_TCP; 261 if (strstr(buf, " -notcp")) 262 options->transports &= ~AFPTRANS_TCP; 263 if (strstr(buf, " -ddp")) 264 options->transports |= AFPTRANS_DDP; 265 if (strstr(buf, " -noddp")) 266 options->transports &= ~AFPTRANS_DDP; 267 if (strstr(buf, "-client_polling")) 268 options->server_notif = 0; 269 270 /* figure out options w/ values. currently, this will ignore the setting 271 * if memory is lacking. */ 272 273 if ((c = getoption(buf, "-hostname"))) { 274 int len = strlen (c); 275 if (len <= MAXHOSTNAMELEN) { 276 memcpy(options->hostname, c, len); 277 options->hostname[len] = 0; 278 } 279 else 280 LOG(log_info, logtype_afpd, "WARNING: hostname %s is too long (%d)",c,len); 281 } 282 283 if ((c = getoption(buf, "-defaultvol")) && (opt = strdup(c))) 284 options->defaultvol.name = opt; 285 if ((c = getoption(buf, "-systemvol")) && (opt = strdup(c))) 286 options->systemvol.name = opt; 287 if ((c = getoption(buf, "-loginmesg")) && (opt = strdup(c))) { 288 int i = 0, j = 0; 289 while (c[i]) { 290 if (c[i] != '\\') { 291 opt[j++] = c[i]; 292 } else { 293 i++; 294 if (c[i] == 'n') 295 opt[j++] = '\n'; 296 } 297 i++; 298 } 299 opt[j] = 0; 300 options->loginmesg = opt; 301 302 } 303 if ((c = getoption(buf, "-guestname")) && (opt = strdup(c))) 304 options->guest = opt; 305 if ((c = getoption(buf, "-passwdfile")) && (opt = strdup(c))) 306 options->passwdfile = opt; 307 if ((c = getoption(buf, "-passwdminlen"))) 308 options->passwdminlen = MIN(1, atoi(c)); 309 if ((c = getoption(buf, "-loginmaxfail"))) 310 options->loginmaxfail = atoi(c); 311 if ((c = getoption(buf, "-tickleval"))) { 312 options->tickleval = atoi(c); 313 if (options->tickleval <= 0) { 314 options->tickleval = 30; 315 } 316 } 317 if ((c = getoption(buf, "-timeout"))) { 318 options->timeout = atoi(c); 319 if (options->timeout <= 0) { 320 options->timeout = 4; 321 } 322 } 323 324 if ((c = getoption(buf, "-sleep"))) { 325 options->sleep = atoi(c) *120; 326 if (options->sleep <= 4) { 327 options->sleep = 4; 328 } 329 } 330 331 if ((c = getoption(buf, "-dsireadbuf"))) { 332 options->dsireadbuf = atoi(c); 333 if (options->dsireadbuf < 6) 334 options->dsireadbuf = 6; 335 } 336 337 if ((c = getoption(buf, "-server_quantum"))) 338 options->server_quantum = strtoul(c, NULL, 0); 339 340 if ((c = getoption(buf, "-volnamelen"))) { 341 options->volnamelen = atoi(c); 342 if (options->volnamelen < 8) { 343 options->volnamelen = 8; /* max mangled volname "???#FFFF" */ 344 } 345 if (options->volnamelen > 255) { 346 options->volnamelen = 255; /* AFP3 spec */ 347 } 348 } 349 350 /* -[no]setuplog <logtype> <loglevel> [<filename>]*/ 351 c = buf; 352 /* Now THIS is hokey! Multiple occurrences are not supported by our current code, */ 353 /* so I have to loop myself. */ 354 while (NULL != (c = strstr(c, "-setuplog"))) { 355 char *optstr; 356 if ((optstr = getoption(c, "-setuplog"))) { 357 /* hokey2: options->logconfig must be converted to store an array of logstrings */ 358 if (options->logconfig) 359 free(options->logconfig); 360 options->logconfig = strdup(optstr); 361 setuplog(optstr); 362 c += sizeof("-setuplog"); 363 } 364 } 365 366 if ((c = getoption(buf, "-unsetuplog"))) 367 unsetuplog(c); 368 369#ifdef ADMIN_GRP 370 if ((c = getoption(buf, "-admingroup"))) { 371 struct group *gr = getgrnam(c); 372 if (gr != NULL) { 373 options->admingid = gr->gr_gid; 374 } 375 } 376#endif /* ADMIN_GRP */ 377 378 if ((c = getoption(buf, "-k5service")) && (opt = strdup(c))) 379 options->k5service = opt; 380 if ((c = getoption(buf, "-k5realm")) && (opt = strdup(c))) 381 options->k5realm = opt; 382 if ((c = getoption(buf, "-k5keytab"))) { 383 if ( NULL == (options->k5keytab = (char *) malloc(sizeof(char)*(strlen(c)+14)) )) { 384 LOG(log_error, logtype_afpd, "malloc failed"); 385 exit(-1); 386 } 387 snprintf(options->k5keytab, strlen(c)+14, "KRB5_KTNAME=%s", c); 388 putenv(options->k5keytab); 389 /* setenv( "KRB5_KTNAME", c, 1 ); */ 390 } 391 if ((c = getoption(buf, "-authprintdir")) && (opt = strdup(c))) 392 options->authprintdir = opt; 393 if ((c = getoption(buf, "-uampath")) && (opt = strdup(c))) 394 options->uampath = opt; 395 if ((c = getoption(buf, "-uamlist")) && (opt = strdup(c))) 396 options->uamlist = opt; 397 398 if ((c = getoption(buf, "-ipaddr"))) { 399#if 0 400 struct in_addr inaddr; 401 if (inet_aton(c, &inaddr) && (opt = strdup(c))) { 402 if (!gethostbyaddr((const char *) &inaddr, sizeof(inaddr), AF_INET)) 403 LOG(log_info, logtype_afpd, "WARNING: can't find %s", opt); 404 options->ipaddr = opt; 405 } 406 else { 407 LOG(log_error, logtype_afpd, "Error parsing -ipaddr, is %s in numbers-and-dots notation?", c); 408 } 409#endif 410 options->ipaddr = strdup(c); 411 } 412 413 /* FIXME CNID Cnid_srv is a server attribute */ 414 if ((c = getoption(buf, "-cnidserver"))) { 415 char *p = strrchr(c, ':'); 416 if (p) 417 *p = 0; 418 Cnid_srv = strdup(c); 419 if (p) 420 Cnid_port = strdup(p + 1); 421 LOG(log_debug, logtype_afpd, "CNID Server: %s:%s", Cnid_srv, Cnid_port); 422 } 423 424 if ((c = getoption(buf, "-port"))) 425 options->port = strdup(c); 426 if ((c = getoption(buf, "-ddpaddr"))) 427 atalk_aton(c, &options->ddpaddr); 428 if ((c = getoption(buf, "-signature")) && (opt = strdup(c))) 429 options->signatureopt = opt; 430 431 /* do a little checking for the domain name. */ 432 if ((c = getoption(buf, "-fqdn"))) { 433 char *p = strchr(c, ':'); 434 if (p) 435 *p = '\0'; 436 if (gethostbyname(c)) { 437 if (p) 438 *p = ':'; 439 if ((opt = strdup(c))) 440 options->fqdn = opt; 441 } 442 else { 443 LOG(log_error, logtype_afpd, "error parsing -fqdn, gethostbyname failed for: %s", c); 444 } 445 } 446 447 if ((c = getoption(buf, "-unixcodepage"))) { 448 if ((charset_t)-1 == ( options->unixcharset = add_charset(c)) ) { 449 options->unixcharset = CH_UNIX; 450 LOG(log_warning, logtype_afpd, "setting Unix codepage to '%s' failed", c); 451 } 452 else { 453 if ((opt = strdup(c))) 454 options->unixcodepage = opt; 455 } 456 } 457 458 if ((c = getoption(buf, "-maccodepage"))) { 459 if ((charset_t)-1 == ( options->maccharset = add_charset(c)) ) { 460 options->maccharset = CH_MAC; 461 LOG(log_warning, logtype_afpd, "setting Mac codepage to '%s' failed", c); 462 } 463 else { 464 if ((opt = strdup(c))) 465 options->maccodepage = opt; 466 } 467 } 468 469 if ((c = strstr(buf, "-closevol"))) { 470 options->closevol= 1; 471 } 472 473 if ((c = getoption(buf, "-ntdomain")) && (opt = strdup(c))) 474 options->ntdomain = opt; 475 476 if ((c = getoption(buf, "-ntseparator")) && (opt = strdup(c))) 477 options->ntseparator = opt; 478 479 if ((c = getoption(buf, "-dircachesize"))) 480 options->dircachesize = atoi(c); 481 482 if ((c = getoption(buf, "-tcpsndbuf"))) 483 options->tcp_sndbuf = atoi(c); 484 485 if ((c = getoption(buf, "-tcprcvbuf"))) 486 options->tcp_rcvbuf = atoi(c); 487 488 if ((c = getoption(buf, "-fcelistener"))) { 489 LOG(log_note, logtype_afpd, "Adding fce listener \"%s\"", c); 490 fce_add_udp_socket(c); 491 } 492 if ((c = getoption(buf, "-fcecoalesce"))) { 493 LOG(log_note, logtype_afpd, "Fce coalesce: %s", c); 494 fce_set_coalesce(c); 495 } 496 if ((c = getoption(buf, "-fceevents"))) { 497 LOG(log_note, logtype_afpd, "Fce events: %s", c); 498 fce_set_events(c); 499 } 500 501 if ((c = getoption(buf, "-mimicmodel")) && (opt = strdup(c))) 502 options->mimicmodel = opt; 503 504 return 1; 505} 506 507/* 508 * Show version information about afpd. 509 * Used by "afp -v". 510 */ 511static void show_version( void ) 512{ 513 printf( "afpd %s - Apple Filing Protocol (AFP) daemon of Netatalk\n\n", VERSION ); 514 515 puts( "This program is free software; you can redistribute it and/or modify it under" ); 516 puts( "the terms of the GNU General Public License as published by the Free Software" ); 517 puts( "Foundation; either version 2 of the License, or (at your option) any later" ); 518 puts( "version. Please see the file COPYING for further information and details.\n" ); 519 520 puts( "afpd has been compiled with support for these features:\n" ); 521 522 printf( " AFP3.x support:\tYes\n" ); 523 printf( " TCP/IP Support:\t" ); 524 puts( "Yes" ); 525 526 printf( "DDP(AppleTalk) Support:\t" ); 527#ifdef NO_DDP 528 puts( "No" ); 529#else 530 puts( "Yes" ); 531#endif 532 533 printf( " CNID backends:\t" ); 534#ifdef CNID_BACKEND_CDB 535 printf( "cdb "); 536#endif 537#ifdef CNID_BACKEND_DB3 538 printf( "db3 " ); 539#endif 540#ifdef CNID_BACKEND_DBD 541#ifdef CNID_BACKEND_DBD_TXN 542 printf( "dbd-txn " ); 543#else 544 printf( "dbd " ); 545#endif 546#endif 547#ifdef CNID_BACKEND_HASH 548 printf( "hash " ); 549#endif 550#ifdef CNID_BACKEND_LAST 551 printf( "last " ); 552#endif 553#ifdef CNID_BACKEND_MTAB 554 printf( "mtab " ); 555#endif 556#ifdef CNID_BACKEND_TDB 557 printf( "tdb " ); 558#endif 559 puts( "" ); 560} 561 562/* 563 * Show extended version information about afpd and Netatalk. 564 * Used by "afp -V". 565 */ 566static void show_version_extended(void ) 567{ 568 show_version( ); 569 570 printf( " SLP support:\t" ); 571#ifdef USE_SRVLOC 572 puts( "Yes" ); 573#else 574 puts( "No" ); 575#endif 576 577 printf( " Zeroconf support:\t" ); 578#ifdef USE_ZEROCONF 579 puts( "Yes" ); 580#else 581 puts( "No" ); 582#endif 583 584 printf( " TCP wrappers support:\t" ); 585#ifdef TCPWRAP 586 puts( "Yes" ); 587#else 588 puts( "No" ); 589#endif 590 591 printf( " Quota support:\t" ); 592#ifndef NO_QUOTA_SUPPORT 593 puts( "Yes" ); 594#else 595 puts( "No" ); 596#endif 597 598 printf( " Admin group support:\t" ); 599#ifdef ADMIN_GRP 600 puts( "Yes" ); 601#else 602 puts( "No" ); 603#endif 604 605 printf( " Valid shell checks:\t" ); 606#ifndef DISABLE_SHELLCHECK 607 puts( "Yes" ); 608#else 609 puts( "No" ); 610#endif 611 612 printf( " cracklib support:\t" ); 613#ifdef USE_CRACKLIB 614 puts( "Yes" ); 615#else 616 puts( "No" ); 617#endif 618 619 printf( " Dropbox kludge:\t" ); 620#ifdef DROPKLUDGE 621 puts( "Yes" ); 622#else 623 puts( "No" ); 624#endif 625 626 printf( " Force volume uid/gid:\t" ); 627#ifdef FORCE_UIDGID 628 puts( "Yes" ); 629#else 630 puts( "No" ); 631#endif 632 633 printf( " ACL support:\t" ); 634#ifdef HAVE_ACLS 635 puts( "Yes" ); 636#else 637 puts( "No" ); 638#endif 639 640 printf( " EA support:\t" ); 641 puts( EA_MODULES ); 642 643 printf( " LDAP support:\t" ); 644#ifdef HAVE_LDAP 645 puts( "Yes" ); 646#else 647 puts( "No" ); 648#endif 649} 650 651/* 652 * Display compiled-in default paths 653 */ 654static void show_paths( void ) 655{ 656 printf( " afpd.conf:\t%s\n", _PATH_AFPDCONF ); 657 printf( " AppleVolumes.system:\t%s\n", _PATH_AFPDSYSVOL ); 658 printf( " AppleVolumes.default:\t%s\n", _PATH_AFPDDEFVOL ); 659 printf( " afp_signature.conf:\t%s\n", _PATH_AFPDSIGCONF ); 660 printf( " afp_voluuid.conf:\t%s\n", _PATH_AFPDUUIDCONF ); 661#ifdef HAVE_LDAP 662 printf( " afp_ldap.conf:\t%s\n", _PATH_ACL_LDAPCONF ); 663#else 664 printf( " afp_ldap.conf:\tnot supported\n"); 665#endif 666 printf( " UAM search path:\t%s\n", _PATH_AFPDUAMPATH ); 667 printf( " Server messages path:\t%s\n", SERVERTEXT); 668 printf( " lockfile:\t%s\n", _PATH_AFPDLOCK); 669} 670 671/* 672 * Display usage information about afpd. 673 */ 674static void show_usage( char *name ) 675{ 676 fprintf( stderr, "Usage:\t%s [-duptDTI] [-f defaultvolumes] [-s systemvolumes] [-n nbpname]\n", name ); 677 fprintf( stderr, "\t [-c maxconnections] [-g guest] [-P pidfile] [-S port] [-L message]\n" ); 678 fprintf( stderr, "\t [-F configfile] [-U uams] [-m umask]\n" ); 679 fprintf( stderr, "\t%s -h|-v|-V\n", name ); 680} 681 682int afp_options_parse(int ac, char **av, struct afp_options *options) 683{ 684 extern char *optarg; 685 extern int optind; 686 687 char *p; 688 char *tmp; /* Used for error checking the result of strtol */ 689 int c, err = 0; 690 691 if (gethostname(options->hostname, sizeof(options->hostname )) < 0 ) { 692 perror( "gethostname" ); 693 return 0; 694 } 695 if (NULL != ( p = strchr(options->hostname, '.' )) ) { 696 *p = '\0'; 697 } 698 699 if (NULL == ( p = strrchr( av[ 0 ], '/' )) ) { 700 p = av[ 0 ]; 701 } else { 702 p++; 703 } 704 705 while (EOF != ( c = getopt( ac, av, OPTIONS )) ) { 706 switch ( c ) { 707 case 'd' : 708 options->flags |= OPTION_DEBUG; 709 break; 710 case 'n' : 711 options->server = optarg; 712 break; 713 case 'f' : 714 options->defaultvol.name = optarg; 715 break; 716 case 's' : 717 options->systemvol.name = optarg; 718 break; 719 case 'u' : 720 options->flags |= OPTION_USERVOLFIRST; 721 break; 722 case 'c' : 723 options->connections = atoi( optarg ); 724 break; 725 case 'g' : 726 options->guest = optarg; 727 break; 728 729 case 'P' : 730 options->pidfile = optarg; 731 break; 732 733 case 'p': 734 options->passwdbits |= PASSWD_NOSAVE; 735 break; 736 case 't': 737 options->passwdbits |= PASSWD_SET; 738 break; 739 740 case 'D': 741 options->transports &= ~AFPTRANS_DDP; 742 break; 743 case 'S': 744 options->port = optarg; 745 break; 746 case 'T': 747 options->transports &= ~AFPTRANS_TCP; 748 break; 749 case 'L': 750 options->loginmesg = optarg; 751 break; 752 case 'F': 753 options->configfile = optarg; 754 break; 755 case 'U': 756 options->uamlist = optarg; 757 break; 758 case 'v': /* version */ 759 show_version( ); puts( "" ); 760 show_paths( ); puts( "" ); 761 exit( 0 ); 762 break; 763 case 'V': /* extended version */ 764 show_version_extended( ); puts( "" ); 765 show_paths( ); puts( "" ); 766 exit( 0 ); 767 break; 768 case 'h': /* usage */ 769 show_usage( p ); 770 exit( 0 ); 771 break; 772 case 'I': 773 options->flags |= OPTION_CUSTOMICON; 774 break; 775 case 'm': 776 options->umask = strtoul(optarg, &tmp, 8); 777 if ((options->umask > 0777)) { 778 fprintf(stderr, "%s: out of range umask setting provided\n", p); 779 err++; 780 } 781 if (tmp[0] != '\0') { 782 fprintf(stderr, "%s: invalid characters in umask setting provided\n", p); 783 err++; 784 } 785 break; 786 default : 787 err++; 788 } 789 } 790 if ( err || optind != ac ) { 791 show_usage( p ); 792 exit( 2 ); 793 } 794 795#ifdef ultrix 796 openlog( p, LOG_PID ); /* ultrix only */ 797#else 798 set_processname(p); 799#endif /* ultrix */ 800 801 return 1; 802} 803