~ubuntu-branches/ubuntu/utopic/smb4k/utopic-proposed

« back to all changes in this revision

Viewing changes to utilities/smb4k_umount.cpp

  • Committer: Package Import Robot
  • Author(s): Fathi Boudra
  • Date: 2012-05-19 18:54:34 UTC
  • mfrom: (1.1.20)
  • Revision ID: package-import@ubuntu.com-20120519185434-duffny2n87214n1n
Tags: 1.0.1-1
* New upstream release.
* Update debian/compat: bump to 9.
* Update debian/control:
  - bump debhelper to 9.
  - bump kdelibs5-dev build dependency to 4:4.4.0.
  - bump Standards-Version to 3.9.3 (no changes needed).
  - Replace smbfs dependency by cifs-utils. (Closes: #638162)
* Update debian/copyright:
  - update upstream URL.
  - update upstream e-mail.
* Update debian/smb4k.lintian-overrides file.
* Update debian/watch file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
    smb4k_umount  -  This is the unmount utility of Smb4K.
3
 
                             -------------------
4
 
    begin                : Sa Sep 25 2004
5
 
    copyright            : (C) 2004-2007 by Alexander Reinholdt
6
 
    email                : dustpuppy@users.berlios.de
7
 
 ***************************************************************************/
8
 
 
9
 
/***************************************************************************
10
 
 *   This program is free software; you can redistribute it and/or modify  *
11
 
 *   it under the terms of the GNU General Public License as published by  *
12
 
 *   the Free Software Foundation; either version 2 of the License, or     *
13
 
 *   (at your option) any later version.                                   *
14
 
 *                                                                         *
15
 
 *   This program is distributed in the hope that it will be useful, but   *
16
 
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
17
 
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
18
 
 *   General Public License for more details.                              *
19
 
 *                                                                         *
20
 
 *   You should have received a copy of the GNU General Public License     *
21
 
 *   along with this program; if not, write to the                         *
22
 
 *   Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,   *
23
 
 *   MA  02111-1307 USA                                                    *
24
 
 ***************************************************************************/
25
 
 
26
 
#ifdef HAVE_CONFIG_H
27
 
#include <config.h>
28
 
#endif
29
 
 
30
 
#ifndef __FreeBSD__
31
 
#include <sys/statfs.h>
32
 
#else
33
 
#include <sys/param.h>
34
 
#include <sys/mount.h>
35
 
#endif
36
 
 
37
 
#ifdef __linux__
38
 
#include <sys/utsname.h>
39
 
#endif
40
 
 
41
 
#include <locale.h>
42
 
#include <unistd.h>
43
 
#include <getopt.h>
44
 
#include <errno.h>
45
 
#include <string.h>
46
 
#include <stdlib.h>
47
 
#include <iostream>
48
 
using namespace std;
49
 
 
50
 
#define SMB4K_UMOUNT_VERSION "0.15"
51
 
 
52
 
 
53
 
void info()
54
 
{
55
 
        cout << "This is smb4k_umount (version " << SMB4K_UMOUNT_VERSION << "), the unmount utility of Smb4K" << endl;
56
 
        cout << "Copyright (C) 2004-2008, Alexander Reinholdt" << endl;
57
 
        cout << endl;
58
 
        cout << "Usage:" << endl;
59
 
#ifndef __FreeBSD__
60
 
        cout << "  smb4k_umount {mode} {options} {mountpoint}" << endl;
61
 
#else
62
 
        cout << "  smb4k_umount {mountpoint}" << endl;
63
 
#endif
64
 
        cout << "  smb4k_umount --help" << endl;
65
 
        cout << "  smb4k_umount --version" << endl;
66
 
        cout << endl;
67
 
        cout << "Arguments:" << endl;
68
 
        cout << "  {mode}" << endl;
69
 
#ifndef __FreeBSD__
70
 
        cout << "    --no-suid\tsmb4k_umount is run in normal user mode, so smbumount or" << endl;
71
 
        cout << "\t\tumount.cifs is invoked." << endl;
72
 
        cout << "    --suid\tsmb4k_umount is run in super user mode, so umount is invoked." << endl;
73
 
        cout << "    -n\t\tThe same as the '--no-suid' argument." << endl;
74
 
        cout << "    -s\t\tThe same as the '--suid' argument." << endl;
75
 
        cout << endl;
76
 
        cout << "  {options}" << endl;
77
 
        cout << "    -t <fs>\tThe file system that should be used for unmounting. Only 'smbfs'" << endl;
78
 
        cout << "\t\tand 'cifs' are supported. All other file systems will result in" << endl;
79
 
                cout << "\t\tan error. Please note, that this argument is mandatory." << endl;
80
 
#endif
81
 
#ifdef __linux__
82
 
        cout << "    -l\t\tPerform a lazy unmount. See the manual page of umount for" << endl;
83
 
        cout << "\t\tmore information. Please note, that this argument is only" << endl;
84
 
        cout << "\t\trecognized in super user mode, i.e. if '-s' or '--suid' is" << endl;
85
 
        cout << "\t\t supplied, and that you need kernel version 2.4.11 or later." << endl;
86
 
#endif
87
 
        cout << endl;
88
 
        cout << "  {mountpoint}\tThe path where the share is mounted." << endl;
89
 
        cout << endl;
90
 
        cout << "  --help\tDisplay this help screen and exit." << endl;
91
 
        cout << "  --version\tDisplay the version information and exit." << endl;
92
 
        cout << endl;
93
 
}
94
 
 
95
 
 
96
 
void version()
97
 
{
98
 
        cout << "Version " << SMB4K_UMOUNT_VERSION << endl;
99
 
}
100
 
 
101
 
 
102
 
bool find_program( const char *name, char *path )
103
 
{
104
 
        const char *paths[] = { "/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/", "/usr/local/bin/", "/usr/local/sbin/" };
105
 
        string file = "";
106
 
 
107
 
        for ( uint i = 0; i < sizeof( paths ) / sizeof( char * ); i++ )
108
 
        {
109
 
                string p( paths[i] );
110
 
                p.append( name );
111
 
 
112
 
                if ( access( p.c_str(), X_OK ) == 0 )
113
 
                {
114
 
                        file.assign( p );
115
 
                        break;
116
 
                }
117
 
        }
118
 
 
119
 
        if ( !strcmp( file.c_str(), "" ) )
120
 
        {
121
 
                cerr << "smb4k_umount: Could not find " << name << " binary" << endl;
122
 
 
123
 
                return false;
124
 
        }
125
 
 
126
 
        int len = strlen( file.c_str() ) + 1;
127
 
        strncpy( path, file.c_str(), len );
128
 
        path[len-1] = '\0';
129
 
 
130
 
        return true;
131
 
}
132
 
 
133
 
 
134
 
bool check_filesystem( const char *path, const char *fs )
135
 
{
136
 
        bool ok = false;
137
 
 
138
 
        struct statfs filesystem;
139
 
 
140
 
        if ( statfs( path, &filesystem ) == -1 )
141
 
        {
142
 
                int err_code = errno;
143
 
 
144
 
                if ( err_code != EIO && err_code != EACCES )
145
 
                {
146
 
                        // ok is still FALSE
147
 
                        cerr << "smb4k_umount: " << strerror( err_code ) << endl;
148
 
                }
149
 
                else
150
 
                {
151
 
                        ok = true; // Bypass the check below, because it would yield ok == FALSE
152
 
                                   // and we want to be able to unmount broken shares as well.
153
 
                }
154
 
 
155
 
                return ok;
156
 
        }
157
 
 
158
 
#ifndef __FreeBSD__
159
 
        // First entry is for CIFS, the second for SMBFS.
160
 
        if ( (uint)filesystem.f_type == 0xFF534D42 && !strncmp( fs, "cifs", strlen( fs )+1 ) )
161
 
        {
162
 
                ok = true;
163
 
        }
164
 
        else if ( (uint)filesystem.f_type == 0x517B && !strncmp( fs, "smbfs", strlen( fs )+1 ) )
165
 
        {
166
 
                ok = true;
167
 
        }
168
 
#else
169
 
        if ( !strncmp( filesystem.f_fstypename, fs, strlen( fs ) ) )
170
 
        {
171
 
                ok = true;
172
 
        }
173
 
#endif
174
 
        else
175
 
        {
176
 
                // ok is still FALSE.
177
 
                cerr << "smb4k_umount: Wrong file system specified" << endl;
178
 
        }
179
 
 
180
 
        return ok;
181
 
}
182
 
 
183
 
 
184
 
int main( int argc, char *argv[], char *envp[] )
185
 
{
186
 
        // First of all, set the locale
187
 
        (void) setlocale( LC_ALL, "" );
188
 
 
189
 
        if ( argc < 2 )
190
 
        {
191
 
                info();
192
 
                exit( EXIT_FAILURE );
193
 
        }
194
 
 
195
 
        int new_argc = argc + 1;
196
 
        char *new_argv[new_argc];
197
 
        int index = 0;
198
 
        char path[255];
199
 
        path[0] = '\0';
200
 
        char *mountpoint = NULL;
201
 
#ifndef __FreeBSD__
202
 
        char *filesystem = NULL;
203
 
        bool normal_user_mode = true;
204
 
        bool have_user_mode = false;
205
 
#ifdef __linux__
206
 
        bool lazy_unmount = false;
207
 
#endif
208
 
#endif
209
 
 
210
 
        // Get the options that were passed:
211
 
        int c;
212
 
 
213
 
        while ( 1 )
214
 
        {
215
 
                int option_index = 0;
216
 
 
217
 
                static struct option long_options[] =
218
 
                {
219
 
                        { "help", 0, 0, 0 },
220
 
                        { "version", 0, 0, 0 },
221
 
#ifndef __FreeBSD__
222
 
                        { "suid", 0, 0, 0 },
223
 
                        { "no-suid", 0, 0, 0 },
224
 
#endif
225
 
                        { 0, 0, 0, 0 }
226
 
                };
227
 
#ifdef __linux__
228
 
                c = getopt_long( argc, argv, "t:nsl", long_options, &option_index );
229
 
#else
230
 
#ifndef __FreeBSD__
231
 
                c = getopt_long( argc, argv, "t:ns", long_options, &option_index );
232
 
#else
233
 
                c = getopt_long( argc, argv, "", long_options, &option_index );
234
 
#endif
235
 
#endif
236
 
 
237
 
                if ( c == -1 )
238
 
                {
239
 
                        break;
240
 
                }
241
 
 
242
 
                switch ( c )
243
 
                {
244
 
                        case 0:
245
 
                        {
246
 
                                int len = strlen( long_options[option_index].name ) + 1;
247
 
                                char opt[len];
248
 
                                opt[0] = '\0';
249
 
                                (void) strncpy( opt, long_options[option_index].name, len );
250
 
                                opt[len-1] = '\0';
251
 
 
252
 
                                if ( !strncmp( opt, "help", len ) )
253
 
                                {
254
 
                                        info();
255
 
 
256
 
                                        exit( EXIT_SUCCESS );
257
 
                                }
258
 
                                else if ( !strncmp( opt, "version", len ) )
259
 
                                {
260
 
                                        version();
261
 
 
262
 
                                        exit( EXIT_SUCCESS );
263
 
                                }
264
 
#ifndef __FreeBSD__
265
 
                                else if ( !strncmp( opt, "suid", len ) )
266
 
                                {
267
 
                                        // Enter super user mode
268
 
 
269
 
                                        normal_user_mode = false;
270
 
                                        have_user_mode = true;
271
 
 
272
 
                                        break;
273
 
                                }
274
 
                                else if ( !strncmp( opt, "no-suid", len ) )
275
 
                                {
276
 
                                        // Enter normal user mode
277
 
 
278
 
                                        normal_user_mode = true;
279
 
                                        have_user_mode = true;
280
 
 
281
 
                                        break;
282
 
                                }
283
 
#endif
284
 
                                else
285
 
                                {
286
 
                                        break;
287
 
                                }
288
 
 
289
 
                                break;
290
 
                        }
291
 
#ifndef __FreeBSD__
292
 
                        case 't':
293
 
                        {
294
 
                                // Get the length of the option argument:
295
 
                                int len = strlen( optarg ) + 1;
296
 
 
297
 
                                if ( strncmp( "smbfs", optarg, len) != 0 &&
298
 
                                     strncmp( "cifs", optarg, len ) != 0 )
299
 
                                {
300
 
                                        cerr << "smb4k_umount: File system " << optarg << " is not supported" << endl;
301
 
                                        exit( EXIT_FAILURE );
302
 
                                }
303
 
 
304
 
                                if ( !filesystem )
305
 
                                {
306
 
                                        filesystem = new char[len];
307
 
                                        filesystem[0] = '\0';
308
 
                                        (void) strncpy( filesystem, optarg, len );
309
 
                                        filesystem[len-1] = '\0';
310
 
                                }
311
 
 
312
 
                                break;
313
 
                        }
314
 
                        case 's':
315
 
                        {
316
 
                                // Enter super user mode
317
 
                                normal_user_mode = false;
318
 
                                have_user_mode = true;
319
 
 
320
 
                                break;
321
 
                        }
322
 
                        case 'n':
323
 
                        {
324
 
                                // Enter normal user mode
325
 
                                normal_user_mode = true;
326
 
                                have_user_mode = true;
327
 
 
328
 
                                break;
329
 
                        }
330
 
#endif
331
 
#ifdef __linux__
332
 
                        case 'l':
333
 
                        {
334
 
                                // Initiate a lazy unmount. The umount binary
335
 
                                // will complain, if '-l' is not supported.
336
 
                                lazy_unmount = true;
337
 
 
338
 
                                break;
339
 
                        }
340
 
#endif
341
 
                        case '?':
342
 
                        {
343
 
                                // Abort the program if an unknown option
344
 
                                // is encountered:
345
 
                                exit( EXIT_FAILURE );
346
 
                        }
347
 
                        default:
348
 
                        {
349
 
                                break;
350
 
                        }
351
 
                };
352
 
        }
353
 
 
354
 
#ifndef __FreeBSD__
355
 
        // Error out if no user mode was specified.
356
 
        if ( !have_user_mode )
357
 
        {
358
 
                cerr << "smb4k_umount: No mode was specified" << endl;
359
 
                exit( EXIT_FAILURE );
360
 
        }
361
 
 
362
 
        // Error out if the user did not specify any file system.
363
 
        if ( !filesystem )
364
 
        {
365
 
                cerr << "smb4k_umount: No file system was specified" << endl;
366
 
                exit( EXIT_FAILURE );
367
 
        }
368
 
 
369
 
        if ( normal_user_mode )
370
 
        {
371
 
                int len = strlen( filesystem ) + 1;
372
 
 
373
 
                if ( !strncmp( "smbfs", filesystem, len ) )
374
 
                {
375
 
                        if ( !find_program( "smbumount", path ) )
376
 
                        {
377
 
                                exit( EXIT_FAILURE );
378
 
                        }
379
 
                }
380
 
                else
381
 
                {
382
 
                        if ( !find_program( "umount.cifs", path ) )
383
 
                        {
384
 
                          if ( !find_program( "umount", path ) )
385
 
                          {
386
 
                                exit( EXIT_FAILURE );
387
 
                          }
388
 
                        }
389
 
                }
390
 
 
391
 
                len = strlen( path ) + 1;
392
 
 
393
 
                new_argv[index] = new char[len];
394
 
                new_argv[index][0] = '\0';
395
 
                (void) strncpy( new_argv[index], path, len );
396
 
                new_argv[index][len-1] = '\0';
397
 
 
398
 
                index++;
399
 
        }
400
 
        else
401
 
        {
402
 
                if ( !find_program( "umount", path ) )
403
 
                {
404
 
                        exit( EXIT_FAILURE );
405
 
                }
406
 
 
407
 
                int len = strlen( path ) + 1;
408
 
 
409
 
                new_argv[index] = new char[len];
410
 
                new_argv[index][0] = '\0';
411
 
                (void) strncpy( new_argv[index], path, len );
412
 
                new_argv[index][len-1] = '\0';
413
 
 
414
 
                index++;
415
 
 
416
 
                len = strlen( "-t" ) + 1;
417
 
 
418
 
                new_argv[index] = new char[len];
419
 
                new_argv[index][0] = '\0';
420
 
                (void) strncpy( new_argv[index], "-t", len );
421
 
                new_argv[index][len-1] = '\0';
422
 
 
423
 
                index++;
424
 
 
425
 
                len = strlen( filesystem ) + 1;
426
 
 
427
 
                new_argv[index] = new char[len];
428
 
                new_argv[index][0] = '\0';
429
 
                (void) strncpy( new_argv[index], filesystem, len );
430
 
                new_argv[index][len-1] = '\0';
431
 
 
432
 
                index++;
433
 
 
434
 
#ifdef __linux__
435
 
                // Lazy unmount?
436
 
                if ( lazy_unmount )
437
 
                {
438
 
                        len = strlen( "-l" ) + 1;
439
 
 
440
 
                        new_argv[index] = new char[len];
441
 
                        new_argv[index][0] = '\0';
442
 
                        (void) strncpy( new_argv[index], "-l", len );
443
 
                        new_argv[index][len-1] = '\0';
444
 
 
445
 
                        index++;
446
 
                }
447
 
#endif
448
 
        }
449
 
#else
450
 
        // We do not need to care about the user mode and
451
 
        // we also need not to check for the file system,
452
 
        // since there is only one.
453
 
        if ( !find_program( "umount", path ) )
454
 
        {
455
 
                exit( EXIT_FAILURE );
456
 
        }
457
 
 
458
 
        int length = strlen( path ) + 1;
459
 
        new_argv[index] = new char[length];
460
 
        new_argv[index][0] = '\0';
461
 
        (void) strncpy( new_argv[index], path, length );
462
 
        new_argv[index][length-1] = '\0';
463
 
 
464
 
        index++;
465
 
#endif
466
 
 
467
 
  // Add the mount point:
468
 
        if ( optind < argc )
469
 
        {
470
 
                while ( optind < argc )
471
 
                {
472
 
                        if ( !mountpoint )
473
 
                        {
474
 
                                if ( argv[optind][0] != '\057' )
475
 
                                {
476
 
                                        cerr << "smb4k_umount: Argument " << optind << " is not a mount point" << endl;
477
 
                                        exit( EXIT_FAILURE );
478
 
                                }
479
 
#ifndef __FreeBSD__
480
 
                                if ( !check_filesystem( argv[optind], filesystem  ) )
481
 
#else
482
 
                                if ( !check_filesystem( argv[optind], "smbfs" ) )
483
 
#endif
484
 
                                {
485
 
                                        // Error message is given by check_filesystem()
486
 
                                        exit( EXIT_FAILURE );
487
 
                                }
488
 
 
489
 
                                int len = strlen( argv[optind] ) + 1;
490
 
 
491
 
                                mountpoint = new char[len];
492
 
                                mountpoint[0] = '\0';
493
 
                                (void) strncpy( mountpoint, argv[optind], len );
494
 
                                mountpoint[len-1] = '\0';
495
 
 
496
 
                                optind++;
497
 
                        }
498
 
                        else
499
 
                        {
500
 
                                break;
501
 
                        }
502
 
                }
503
 
        }
504
 
 
505
 
        if ( !mountpoint )
506
 
        {
507
 
                cerr << "smb4k_umount: No mount point was specified" << endl;
508
 
                exit( EXIT_FAILURE );
509
 
        }
510
 
        else
511
 
        {
512
 
                int len = strlen( mountpoint ) + 1;
513
 
                new_argv[index] = new char[len];
514
 
                new_argv[index][0] = '\0';
515
 
                (void) strncpy( new_argv[index], mountpoint, len );
516
 
                new_argv[index][len-1] = '\0';
517
 
 
518
 
                index++;
519
 
        }
520
 
 
521
 
 
522
 
        if ( index >= new_argc )
523
 
        {
524
 
                cerr << "smb4k_umount: There are too many arguments" << endl;
525
 
                exit( EXIT_FAILURE );
526
 
        }
527
 
 
528
 
        // Terminate new_argv:
529
 
        new_argv[index] = NULL;
530
 
 
531
 
        // Execute command:
532
 
        if ( execve( new_argv[0], new_argv, envp ) == -1 )
533
 
        {
534
 
                int err = errno;
535
 
                cerr << "smb4k_umount: " <<  strerror( err ) << endl;
536
 
 
537
 
                exit( EXIT_FAILURE );
538
 
        }
539
 
 
540
 
        return EXIT_SUCCESS;
541
 
}
542