Fix typo in WIFSIGNALED (as per Waider's report)
[Samba/gebeck_regimport.git] / source3 / client / smbmount.c
blob508521bedc164d75268fd65940cad4ef772b3c32
1 /*
2 Unix SMB/CIFS implementation.
3 SMBFS mount program
4 Copyright (C) Andrew Tridgell 1999
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #define NO_SYSLOG
23 #include "includes.h"
25 #include <mntent.h>
26 #include <asm/types.h>
27 #include <linux/smb_fs.h>
29 extern BOOL in_client;
30 extern pstring user_socket_options;
32 static pstring credentials;
33 static pstring my_netbios_name;
34 static pstring password;
35 static pstring username;
36 static pstring workgroup;
37 static pstring mpoint;
38 static pstring service;
39 static pstring options;
41 static struct in_addr dest_ip;
42 static BOOL have_ip;
43 static int smb_port = 0;
44 static BOOL got_pass;
45 static uid_t mount_uid;
46 static gid_t mount_gid;
47 static int mount_ro;
48 static unsigned mount_fmask;
49 static unsigned mount_dmask;
51 static void usage(void);
53 static void exit_parent(int sig)
55 /* parent simply exits when child says go... */
56 exit(0);
59 static void daemonize(void)
61 int j, status;
62 pid_t child_pid;
64 signal( SIGTERM, exit_parent );
66 if ((child_pid = sys_fork()) < 0) {
67 DEBUG(0,("could not fork\n"));
70 if (child_pid > 0) {
71 while( 1 ) {
72 j = waitpid( child_pid, &status, 0 );
73 if( j < 0 ) {
74 if( EINTR == errno ) {
75 continue;
77 status = errno;
79 break;
82 /* If we get here - the child exited with some error status */
83 if (WIFSIGNALED(status))
84 exit(128 + WTERMSIG(status));
85 else
86 exit(WEXITSTATUS(status));
89 signal( SIGTERM, SIG_DFL );
90 chdir("/");
93 static void close_our_files(int client_fd)
95 int i;
96 struct rlimit limits;
98 getrlimit(RLIMIT_NOFILE,&limits);
99 for (i = 0; i< limits.rlim_max; i++) {
100 if (i == client_fd)
101 continue;
102 close(i);
106 static void usr1_handler(int x)
108 return;
112 /*****************************************************
113 return a connection to a server
114 *******************************************************/
115 static struct cli_state *do_connection(char *the_service)
117 struct cli_state *c;
118 struct nmb_name called, calling;
119 char *server_n;
120 struct in_addr ip;
121 pstring server;
122 char *share;
124 if (the_service[0] != '\\' || the_service[1] != '\\') {
125 usage();
126 exit(1);
129 pstrcpy(server, the_service+2);
130 share = strchr_m(server,'\\');
131 if (!share) {
132 usage();
133 exit(1);
135 *share = 0;
136 share++;
138 server_n = server;
140 make_nmb_name(&calling, my_netbios_name, 0x0);
141 make_nmb_name(&called , server, 0x20);
143 again:
144 zero_ip(&ip);
145 if (have_ip) ip = dest_ip;
147 /* have to open a new connection */
148 if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) != smb_port) ||
149 !cli_connect(c, server_n, &ip)) {
150 DEBUG(0,("%d: Connection to %s failed\n", sys_getpid(), server_n));
151 if (c) {
152 cli_shutdown(c);
154 return NULL;
157 /* SPNEGO doesn't work till we get NTSTATUS error support */
158 c->use_spnego = False;
160 /* The kernel doesn't yet know how to sign it's packets */
161 c->sign_info.allow_smb_signing = False;
163 if (!cli_session_request(c, &calling, &called)) {
164 char *p;
165 DEBUG(0,("%d: session request to %s failed (%s)\n",
166 sys_getpid(), called.name, cli_errstr(c)));
167 cli_shutdown(c);
168 if ((p=strchr_m(called.name, '.'))) {
169 *p = 0;
170 goto again;
172 if (strcmp(called.name, "*SMBSERVER")) {
173 make_nmb_name(&called , "*SMBSERVER", 0x20);
174 goto again;
176 return NULL;
179 DEBUG(4,("%d: session request ok\n", sys_getpid()));
181 if (!cli_negprot(c)) {
182 DEBUG(0,("%d: protocol negotiation failed\n", sys_getpid()));
183 cli_shutdown(c);
184 return NULL;
187 if (!got_pass) {
188 char *pass = getpass("Password: ");
189 if (pass) {
190 pstrcpy(password, pass);
194 /* This should be right for current smbfs. Future versions will support
195 large files as well as unicode and oplocks. */
196 c->capabilities &= ~(CAP_UNICODE | CAP_LARGE_FILES | CAP_NT_SMBS |
197 CAP_NT_FIND | CAP_STATUS32 | CAP_LEVEL_II_OPLOCKS);
198 c->force_dos_errors = True;
199 if (!cli_session_setup(c, username,
200 password, strlen(password),
201 password, strlen(password),
202 workgroup)) {
203 /* if a password was not supplied then try again with a
204 null username */
205 if (password[0] || !username[0] ||
206 !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
207 DEBUG(0,("%d: session setup failed: %s\n",
208 sys_getpid(), cli_errstr(c)));
209 cli_shutdown(c);
210 return NULL;
212 DEBUG(0,("Anonymous login successful\n"));
215 DEBUG(4,("%d: session setup ok\n", sys_getpid()));
217 if (!cli_send_tconX(c, share, "?????",
218 password, strlen(password)+1)) {
219 DEBUG(0,("%d: tree connect failed: %s\n",
220 sys_getpid(), cli_errstr(c)));
221 cli_shutdown(c);
222 return NULL;
225 DEBUG(4,("%d: tconx ok\n", sys_getpid()));
227 got_pass = True;
229 return c;
233 /****************************************************************************
234 unmount smbfs (this is a bailout routine to clean up if a reconnect fails)
235 Code blatently stolen from smbumount.c
236 -mhw-
237 ****************************************************************************/
238 static void smb_umount(char *mount_point)
240 int fd;
241 struct mntent *mnt;
242 FILE* mtab;
243 FILE* new_mtab;
245 /* Programmers Note:
246 This routine only gets called to the scene of a disaster
247 to shoot the survivors... A connection that was working
248 has now apparently failed. We have an active mount point
249 (presumably) that we need to dump. If we get errors along
250 the way - make some noise, but we are already turning out
251 the lights to exit anyways...
253 if (umount(mount_point) != 0) {
254 DEBUG(0,("%d: Could not umount %s: %s\n",
255 sys_getpid(), mount_point, strerror(errno)));
256 return;
259 if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
260 DEBUG(0,("%d: Can't get "MOUNTED"~ lock file", sys_getpid()));
261 return;
264 close(fd);
266 if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
267 DEBUG(0,("%d: Can't open " MOUNTED ": %s\n",
268 sys_getpid(), strerror(errno)));
269 return;
272 #define MOUNTED_TMP MOUNTED".tmp"
274 if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
275 DEBUG(0,("%d: Can't open " MOUNTED_TMP ": %s\n",
276 sys_getpid(), strerror(errno)));
277 endmntent(mtab);
278 return;
281 while ((mnt = getmntent(mtab)) != NULL) {
282 if (strcmp(mnt->mnt_dir, mount_point) != 0) {
283 addmntent(new_mtab, mnt);
287 endmntent(mtab);
289 if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
290 DEBUG(0,("%d: Error changing mode of %s: %s\n",
291 sys_getpid(), MOUNTED_TMP, strerror(errno)));
292 return;
295 endmntent(new_mtab);
297 if (rename(MOUNTED_TMP, MOUNTED) < 0) {
298 DEBUG(0,("%d: Cannot rename %s to %s: %s\n",
299 sys_getpid(), MOUNTED, MOUNTED_TMP, strerror(errno)));
300 return;
303 if (unlink(MOUNTED"~") == -1) {
304 DEBUG(0,("%d: Can't remove "MOUNTED"~", sys_getpid()));
305 return;
311 * Call the smbfs ioctl to install a connection socket,
312 * then wait for a signal to reconnect. Note that we do
313 * not exit after open_sockets() or send_login() errors,
314 * as the smbfs mount would then have no way to recover.
316 static void send_fs_socket(char *the_service, char *mount_point, struct cli_state *c)
318 int fd, closed = 0, res = 1;
319 pid_t parentpid = getppid();
320 struct smb_conn_opt conn_options;
322 memset(&conn_options, 0, sizeof(conn_options));
324 while (1) {
325 if ((fd = open(mount_point, O_RDONLY)) < 0) {
326 DEBUG(0,("mount.smbfs[%d]: can't open %s\n",
327 sys_getpid(), mount_point));
328 break;
331 conn_options.fd = c->fd;
332 conn_options.protocol = c->protocol;
333 conn_options.case_handling = SMB_CASE_DEFAULT;
334 conn_options.max_xmit = c->max_xmit;
335 conn_options.server_uid = c->vuid;
336 conn_options.tid = c->cnum;
337 conn_options.secmode = c->sec_mode;
338 conn_options.rawmode = 0;
339 conn_options.sesskey = c->sesskey;
340 conn_options.maxraw = 0;
341 conn_options.capabilities = c->capabilities;
342 conn_options.serverzone = c->serverzone/60;
344 res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
345 if (res != 0) {
346 DEBUG(0,("mount.smbfs[%d]: ioctl failed, res=%d\n",
347 sys_getpid(), res));
348 close(fd);
349 break;
352 if (parentpid) {
353 /* Ok... We are going to kill the parent. Now
354 is the time to break the process group... */
355 setsid();
356 /* Send a signal to the parent to terminate */
357 kill(parentpid, SIGTERM);
358 parentpid = 0;
361 close(fd);
363 /* This looks wierd but we are only closing the userspace
364 side, the connection has already been passed to smbfs and
365 it has increased the usage count on the socket.
367 If we don't do this we will "leak" sockets and memory on
368 each reconnection we have to make. */
369 cli_shutdown(c);
370 c = NULL;
372 if (!closed) {
373 /* redirect stdout & stderr since we can't know that
374 the library functions we use are using DEBUG. */
375 if ( (fd = open("/dev/null", O_WRONLY)) < 0)
376 DEBUG(2,("mount.smbfs: can't open /dev/null\n"));
377 close_our_files(fd);
378 if (fd >= 0) {
379 dup2(fd, STDOUT_FILENO);
380 dup2(fd, STDERR_FILENO);
381 close(fd);
384 /* here we are no longer interactive */
385 set_remote_machine_name("smbmount"); /* sneaky ... */
386 setup_logging("mount.smbfs", False);
387 reopen_logs();
388 DEBUG(0, ("mount.smbfs: entering daemon mode for service %s, pid=%d\n", the_service, sys_getpid()));
390 closed = 1;
393 /* Wait for a signal from smbfs ... but don't continue
394 until we actually get a new connection. */
395 while (!c) {
396 CatchSignal(SIGUSR1, &usr1_handler);
397 pause();
398 DEBUG(2,("mount.smbfs[%d]: got signal, getting new socket\n", sys_getpid()));
399 c = do_connection(the_service);
403 smb_umount(mount_point);
404 DEBUG(2,("mount.smbfs[%d]: exit\n", sys_getpid()));
405 exit(1);
410 * Mount a smbfs
412 static void init_mount(void)
414 char mount_point[MAXPATHLEN+1];
415 pstring tmp;
416 pstring svc2;
417 struct cli_state *c;
418 char *args[20];
419 int i, status;
421 if (realpath(mpoint, mount_point) == NULL) {
422 fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
423 return;
427 c = do_connection(service);
428 if (!c) {
429 fprintf(stderr,"SMB connection failed\n");
430 exit(1);
434 Set up to return as a daemon child and wait in the parent
435 until the child say it's ready...
437 daemonize();
439 pstrcpy(svc2, service);
440 string_replace(svc2, '\\','/');
441 string_replace(svc2, ' ','_');
443 memset(args, 0, sizeof(args[0])*20);
445 i=0;
446 args[i++] = "smbmnt";
448 args[i++] = mount_point;
449 args[i++] = "-s";
450 args[i++] = svc2;
452 if (mount_ro) {
453 args[i++] = "-r";
455 if (mount_uid) {
456 slprintf(tmp, sizeof(tmp)-1, "%d", mount_uid);
457 args[i++] = "-u";
458 args[i++] = smb_xstrdup(tmp);
460 if (mount_gid) {
461 slprintf(tmp, sizeof(tmp)-1, "%d", mount_gid);
462 args[i++] = "-g";
463 args[i++] = smb_xstrdup(tmp);
465 if (mount_fmask) {
466 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_fmask);
467 args[i++] = "-f";
468 args[i++] = smb_xstrdup(tmp);
470 if (mount_dmask) {
471 slprintf(tmp, sizeof(tmp)-1, "0%o", mount_dmask);
472 args[i++] = "-d";
473 args[i++] = smb_xstrdup(tmp);
475 if (options) {
476 args[i++] = "-o";
477 args[i++] = options;
480 if (sys_fork() == 0) {
481 char *smbmnt_path;
483 asprintf(&smbmnt_path, "%s/smbmnt", dyn_BINDIR);
485 if (file_exist(smbmnt_path, NULL)) {
486 execv(smbmnt_path, args);
487 fprintf(stderr,
488 "smbfs/init_mount: execv of %s failed. Error was %s.",
489 smbmnt_path, strerror(errno));
490 } else {
491 execvp("smbmnt", args);
492 fprintf(stderr,
493 "smbfs/init_mount: execv of %s failed. Error was %s.",
494 "smbmnt", strerror(errno));
496 free(smbmnt_path);
497 exit(1);
500 if (waitpid(-1, &status, 0) == -1) {
501 fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
502 /* FIXME: do some proper error handling */
503 exit(1);
506 if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
507 fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
508 /* FIXME: do some proper error handling */
509 exit(1);
510 } else if (WIFSIGNALED(status)) {
511 fprintf(stderr, "smbmnt killed by signal %d\n", WTERMSIG(status));
512 exit(1);
515 /* Ok... This is the rubicon for that mount point... At any point
516 after this, if the connections fail and can not be reconstructed
517 for any reason, we will have to unmount the mount point. There
518 is no exit from the next call...
520 send_fs_socket(service, mount_point, c);
524 /****************************************************************************
525 get a password from a a file or file descriptor
526 exit on failure (from smbclient, move to libsmb or shared .c file?)
527 ****************************************************************************/
528 static void get_password_file(void)
530 int fd = -1;
531 char *p;
532 BOOL close_it = False;
533 pstring spec;
534 char pass[128];
536 if ((p = getenv("PASSWD_FD")) != NULL) {
537 pstrcpy(spec, "descriptor ");
538 pstrcat(spec, p);
539 sscanf(p, "%d", &fd);
540 close_it = False;
541 } else if ((p = getenv("PASSWD_FILE")) != NULL) {
542 fd = sys_open(p, O_RDONLY, 0);
543 pstrcpy(spec, p);
544 if (fd < 0) {
545 fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
546 spec, strerror(errno));
547 exit(1);
549 close_it = True;
552 for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
553 p && p - pass < sizeof(pass);) {
554 switch (read(fd, p, 1)) {
555 case 1:
556 if (*p != '\n' && *p != '\0') {
557 *++p = '\0'; /* advance p, and null-terminate pass */
558 break;
560 case 0:
561 if (p - pass) {
562 *p = '\0'; /* null-terminate it, just in case... */
563 p = NULL; /* then force the loop condition to become false */
564 break;
565 } else {
566 fprintf(stderr, "Error reading password from file %s: %s\n",
567 spec, "empty password\n");
568 exit(1);
571 default:
572 fprintf(stderr, "Error reading password from file %s: %s\n",
573 spec, strerror(errno));
574 exit(1);
577 pstrcpy(password, pass);
578 if (close_it)
579 close(fd);
582 /****************************************************************************
583 get username and password from a credentials file
584 exit on failure (from smbclient, move to libsmb or shared .c file?)
585 ****************************************************************************/
586 static void read_credentials_file(char *filename)
588 FILE *auth;
589 fstring buf;
590 uint16 len = 0;
591 char *ptr, *val, *param;
593 if ((auth=sys_fopen(filename, "r")) == NULL)
595 /* fail if we can't open the credentials file */
596 DEBUG(0,("ERROR: Unable to open credentials file!\n"));
597 exit (-1);
600 while (!feof(auth))
602 /* get a line from the file */
603 if (!fgets (buf, sizeof(buf), auth))
604 continue;
605 len = strlen(buf);
607 if ((len) && (buf[len-1]=='\n'))
609 buf[len-1] = '\0';
610 len--;
612 if (len == 0)
613 continue;
615 /* break up the line into parameter & value.
616 will need to eat a little whitespace possibly */
617 param = buf;
618 if (!(ptr = strchr (buf, '=')))
619 continue;
620 val = ptr+1;
621 *ptr = '\0';
623 /* eat leading white space */
624 while ((*val!='\0') && ((*val==' ') || (*val=='\t')))
625 val++;
627 if (strwicmp("password", param) == 0)
629 pstrcpy(password, val);
630 got_pass = True;
632 else if (strwicmp("username", param) == 0)
633 pstrcpy(username, val);
635 memset(buf, 0, sizeof(buf));
637 fclose(auth);
641 /****************************************************************************
642 usage on the program
643 ****************************************************************************/
644 static void usage(void)
646 printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
648 printf("Version %s\n\n",VERSION);
650 printf(
651 "Options:\n\
652 username=<arg> SMB username\n\
653 password=<arg> SMB password\n\
654 credentials=<filename> file with username/password\n\
655 netbiosname=<arg> source NetBIOS name\n\
656 uid=<arg> mount uid or username\n\
657 gid=<arg> mount gid or groupname\n\
658 port=<arg> remote SMB port number\n\
659 fmask=<arg> file umask\n\
660 dmask=<arg> directory umask\n\
661 debug=<arg> debug level\n\
662 ip=<arg> destination host or IP address\n\
663 workgroup=<arg> workgroup on destination\n\
664 sockopt=<arg> TCP socket options\n\
665 scope=<arg> NetBIOS scope\n\
666 iocharset=<arg> Linux charset (iso8859-1, utf8)\n\
667 codepage=<arg> server codepage (cp850)\n\
668 ttl=<arg> dircache time to live\n\
669 guest don't prompt for a password\n\
670 ro mount read-only\n\
671 rw mount read-write\n\
673 This command is designed to be run from within /bin/mount by giving\n\
674 the option '-t smbfs'. For example:\n\
675 mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test\n\
680 /****************************************************************************
681 Argument parsing for mount.smbfs interface
682 mount will call us like this:
683 mount.smbfs device mountpoint -o <options>
685 <options> is never empty, containing at least rw or ro
686 ****************************************************************************/
687 static void parse_mount_smb(int argc, char **argv)
689 int opt;
690 char *opts;
691 char *opteq;
692 extern char *optarg;
693 int val;
694 char *p;
696 /* FIXME: This function can silently fail if the arguments are
697 * not in the expected order.
699 > The arguments syntax of smbmount 2.2.3a (smbfs of Debian stable)
700 > requires that one gives "-o" before further options like username=...
701 > . Without -o, the username=.. setting is *silently* ignored. I've
702 > spent about an hour trying to find out why I couldn't log in now..
707 if (argc < 2 || argv[1][0] == '-') {
708 usage();
709 exit(1);
712 pstrcpy(service, argv[1]);
713 pstrcpy(mpoint, argv[2]);
715 /* Convert any '/' characters in the service name to
716 '\' characters */
717 string_replace(service, '/','\\');
718 argc -= 2;
719 argv += 2;
721 opt = getopt(argc, argv, "o:");
722 if(opt != 'o') {
723 return;
726 options[0] = 0;
727 p = options;
730 * option parsing from nfsmount.c (util-linux-2.9u)
732 for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
733 DEBUG(3, ("opts: %s\n", opts));
734 if ((opteq = strchr_m(opts, '='))) {
735 val = atoi(opteq + 1);
736 *opteq = '\0';
738 if (!strcmp(opts, "username") ||
739 !strcmp(opts, "logon")) {
740 char *lp;
741 pstrcpy(username,opteq+1);
742 if ((lp=strchr_m(username,'%'))) {
743 *lp = 0;
744 pstrcpy(password,lp+1);
745 got_pass = True;
746 memset(strchr_m(opteq+1,'%')+1,'X',strlen(password));
748 if ((lp=strchr_m(username,'/'))) {
749 *lp = 0;
750 pstrcpy(workgroup,lp+1);
752 } else if(!strcmp(opts, "passwd") ||
753 !strcmp(opts, "password")) {
754 pstrcpy(password,opteq+1);
755 got_pass = True;
756 memset(opteq+1,'X',strlen(password));
757 } else if(!strcmp(opts, "credentials")) {
758 pstrcpy(credentials,opteq+1);
759 } else if(!strcmp(opts, "netbiosname")) {
760 pstrcpy(my_netbios_name,opteq+1);
761 } else if(!strcmp(opts, "uid")) {
762 mount_uid = nametouid(opteq+1);
763 } else if(!strcmp(opts, "gid")) {
764 mount_gid = nametogid(opteq+1);
765 } else if(!strcmp(opts, "port")) {
766 smb_port = val;
767 } else if(!strcmp(opts, "fmask")) {
768 mount_fmask = strtol(opteq+1, NULL, 8);
769 } else if(!strcmp(opts, "dmask")) {
770 mount_dmask = strtol(opteq+1, NULL, 8);
771 } else if(!strcmp(opts, "debug")) {
772 DEBUGLEVEL = val;
773 } else if(!strcmp(opts, "ip")) {
774 dest_ip = *interpret_addr2(opteq+1);
775 if (is_zero_ip(dest_ip)) {
776 fprintf(stderr,"Can't resolve address %s\n", opteq+1);
777 exit(1);
779 have_ip = True;
780 } else if(!strcmp(opts, "workgroup")) {
781 pstrcpy(workgroup,opteq+1);
782 } else if(!strcmp(opts, "sockopt")) {
783 pstrcpy(user_socket_options,opteq+1);
784 } else if(!strcmp(opts, "scope")) {
785 set_global_scope(opteq+1);
786 } else {
787 slprintf(p, sizeof(pstring) - (p - options) - 1, "%s=%s,", opts, opteq+1);
788 p += strlen(p);
790 } else {
791 val = 1;
792 if(!strcmp(opts, "nocaps")) {
793 fprintf(stderr, "Unhandled option: %s\n", opteq+1);
794 exit(1);
795 } else if(!strcmp(opts, "guest")) {
796 *password = '\0';
797 got_pass = True;
798 } else if(!strcmp(opts, "rw")) {
799 mount_ro = 0;
800 } else if(!strcmp(opts, "ro")) {
801 mount_ro = 1;
802 } else {
803 strncpy(p, opts, sizeof(pstring) - (p - options) - 1);
804 p += strlen(opts);
805 *p++ = ',';
806 *p = 0;
811 if (!*service) {
812 usage();
813 exit(1);
816 if (p != options) {
817 *(p-1) = 0; /* remove trailing , */
818 DEBUG(3,("passthrough options '%s'\n", options));
822 /****************************************************************************
823 main program
824 ****************************************************************************/
825 int main(int argc,char *argv[])
827 extern char *optarg;
828 extern int optind;
829 char *p;
831 DEBUGLEVEL = 1;
833 /* here we are interactive, even if run from autofs */
834 setup_logging("mount.smbfs",True);
836 #if 0 /* JRA - Urban says not needed ? */
837 /* CLI_FORCE_ASCII=false makes smbmount negotiate unicode. The default
838 is to not announce any unicode capabilities as current smbfs does
839 not support it. */
840 p = getenv("CLI_FORCE_ASCII");
841 if (p && !strcmp(p, "false"))
842 unsetenv("CLI_FORCE_ASCII");
843 else
844 setenv("CLI_FORCE_ASCII", "true", 1);
845 #endif
847 in_client = True; /* Make sure that we tell lp_load we are */
849 if (getenv("USER")) {
850 pstrcpy(username,getenv("USER"));
852 if ((p=strchr_m(username,'%'))) {
853 *p = 0;
854 pstrcpy(password,p+1);
855 got_pass = True;
856 memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(password));
858 strupper(username);
861 if (getenv("PASSWD")) {
862 pstrcpy(password,getenv("PASSWD"));
863 got_pass = True;
866 if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
867 get_password_file();
868 got_pass = True;
871 if (*username == 0 && getenv("LOGNAME")) {
872 pstrcpy(username,getenv("LOGNAME"));
875 if (!lp_load(dyn_CONFIGFILE,True,False,False)) {
876 fprintf(stderr, "Can't load %s - run testparm to debug it\n",
877 dyn_CONFIGFILE);
880 parse_mount_smb(argc, argv);
882 if (*credentials != 0) {
883 read_credentials_file(credentials);
886 DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
888 if (*workgroup == 0) {
889 pstrcpy(workgroup,lp_workgroup());
892 load_interfaces();
893 if (!*my_netbios_name) {
894 pstrcpy(my_netbios_name, myhostname());
896 strupper(my_netbios_name);
898 init_mount();
899 return 0;