diff options
| -rw-r--r-- | include/applets.h | 2 | ||||
| -rw-r--r-- | include/usage.h | 59 | ||||
| -rw-r--r-- | loginutils/Config.in | 16 | ||||
| -rw-r--r-- | loginutils/Kbuild | 1 | ||||
| -rw-r--r-- | loginutils/cryptpw.c | 144 | ||||
| -rw-r--r-- | loginutils/mkpasswd.c | 71 |
6 files changed, 132 insertions, 161 deletions
diff --git a/include/applets.h b/include/applets.h index 9c844eeae..8d9d2a23b 100644 --- a/include/applets.h +++ b/include/applets.h | |||
| @@ -252,7 +252,7 @@ USE_MKFIFO(APPLET(mkfifo, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |||
| 252 | //USE_MKE2FS(APPLET_ODDNAME(mkfs.ext3, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext3)) | 252 | //USE_MKE2FS(APPLET_ODDNAME(mkfs.ext3, mke2fs, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_ext3)) |
| 253 | USE_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_minix)) | 253 | USE_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, _BB_DIR_SBIN, _BB_SUID_NEVER, mkfs_minix)) |
| 254 | USE_MKNOD(APPLET(mknod, _BB_DIR_BIN, _BB_SUID_NEVER)) | 254 | USE_MKNOD(APPLET(mknod, _BB_DIR_BIN, _BB_SUID_NEVER)) |
| 255 | USE_MKPASSWD(APPLET(mkpasswd, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 255 | USE_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, _BB_DIR_USR_BIN, _BB_SUID_NEVER, mkpasswd)) |
| 256 | USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 256 | USE_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
| 257 | USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) | 257 | USE_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_NEVER)) |
| 258 | USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 258 | USE_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
diff --git a/include/usage.h b/include/usage.h index 8a1d3fa11..90dde95f0 100644 --- a/include/usage.h +++ b/include/usage.h | |||
| @@ -573,18 +573,45 @@ | |||
| 573 | "\n -r Delete crontab" \ | 573 | "\n -r Delete crontab" \ |
| 574 | "\n FILE Replace crontab by FILE ('-': stdin)" \ | 574 | "\n FILE Replace crontab by FILE ('-': stdin)" \ |
| 575 | 575 | ||
| 576 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA | ||
| 577 | #define cryptpw_trivial_usage \ | 576 | #define cryptpw_trivial_usage \ |
| 578 | "[-a des|md5|sha256/512] [string]" | 577 | "[OPTIONS] [PASSWORD] [SALT]" |
| 579 | #else | 578 | /* We do support -s, we just don't mention it */ |
| 580 | #define cryptpw_trivial_usage \ | ||
| 581 | "[-a des|md5] [string]" | ||
| 582 | #endif | ||
| 583 | #define cryptpw_full_usage "\n\n" \ | 579 | #define cryptpw_full_usage "\n\n" \ |
| 584 | "Output crypted string.\n" \ | 580 | "Crypt the PASSWORD using crypt(3)\n" \ |
| 585 | "If string isn't supplied on cmdline, read it from stdin.\n" \ | ||
| 586 | "\nOptions:" \ | 581 | "\nOptions:" \ |
| 587 | "\n -a Algorithm to use (default: md5)" \ | 582 | USE_GETOPT_LONG( \ |
| 583 | "\n -P,--password-fd=NUM Read password from fd NUM" \ | ||
| 584 | /* "\n -s,--stdin Use stdin; like -P0" */ \ | ||
| 585 | "\n -m,--method=TYPE Encryption method TYPE" \ | ||
| 586 | "\n -S,--salt=SALT" \ | ||
| 587 | ) \ | ||
| 588 | SKIP_GETOPT_LONG( \ | ||
| 589 | "\n -P NUM Read password from fd NUM" \ | ||
| 590 | /* "\n -s Use stdin; like -P0" */ \ | ||
| 591 | "\n -m TYPE Encryption method TYPE" \ | ||
| 592 | "\n -S SALT" \ | ||
| 593 | ) \ | ||
| 594 | |||
| 595 | /* mkpasswd is an alias to cryptpw */ | ||
| 596 | |||
| 597 | #define mkpasswd_trivial_usage \ | ||
| 598 | "[OPTIONS] [PASSWORD] [SALT]" | ||
| 599 | /* We do support -s, we just don't mention it */ | ||
| 600 | #define mkpasswd_full_usage "\n\n" \ | ||
| 601 | "Crypt the PASSWORD using crypt(3)\n" \ | ||
| 602 | "\nOptions:" \ | ||
| 603 | USE_GETOPT_LONG( \ | ||
| 604 | "\n -P,--password-fd=NUM Read password from fd NUM" \ | ||
| 605 | /* "\n -s,--stdin Use stdin; like -P0" */ \ | ||
| 606 | "\n -m,--method=TYPE Encryption method TYPE" \ | ||
| 607 | "\n -S,--salt=SALT" \ | ||
| 608 | ) \ | ||
| 609 | SKIP_GETOPT_LONG( \ | ||
| 610 | "\n -P NUM Read password from fd NUM" \ | ||
| 611 | /* "\n -s Use stdin; like -P0" */ \ | ||
| 612 | "\n -m TYPE Encryption method TYPE" \ | ||
| 613 | "\n -S SALT" \ | ||
| 614 | ) \ | ||
| 588 | 615 | ||
| 589 | #define cttyhack_trivial_usage NOUSAGE_STR | 616 | #define cttyhack_trivial_usage NOUSAGE_STR |
| 590 | #define cttyhack_full_usage "" | 617 | #define cttyhack_full_usage "" |
| @@ -2618,20 +2645,6 @@ | |||
| 2618 | "$ mknod /dev/fd0 b 2 0\n" \ | 2645 | "$ mknod /dev/fd0 b 2 0\n" \ |
| 2619 | "$ mknod -m 644 /tmp/pipe p\n" | 2646 | "$ mknod -m 644 /tmp/pipe p\n" |
| 2620 | 2647 | ||
| 2621 | #define mkpasswd_trivial_usage \ | ||
| 2622 | "[OPTIONS] [PASSWORD]" | ||
| 2623 | #define mkpasswd_full_usage "\n\n" \ | ||
| 2624 | "Crypts the PASSWORD using crypt(3)\n" \ | ||
| 2625 | "\nOptions:" \ | ||
| 2626 | "\n\t-P"USE_GETOPT_LONG(", --password-fd=")"NUM\tread password from fd NUM" \ | ||
| 2627 | "\n\t-s"USE_GETOPT_LONG(", --stdin")"\t\tuse stdin; like -P0" \ | ||
| 2628 | "\n\t-m"USE_GETOPT_LONG(", --method=")"TYPE\tEncryption method TYPE" \ | ||
| 2629 | "\n\t-S"USE_GETOPT_LONG(", --salt=")"SALT\t\tuse SALT" | ||
| 2630 | |||
| 2631 | #define mkpasswd_example_usage \ | ||
| 2632 | "$ mkpasswd -m md5\n" \ | ||
| 2633 | "$ mkpasswd -l 12\n" | ||
| 2634 | |||
| 2635 | #define mkswap_trivial_usage \ | 2648 | #define mkswap_trivial_usage \ |
| 2636 | "DEVICE" | 2649 | "DEVICE" |
| 2637 | #define mkswap_full_usage "\n\n" \ | 2650 | #define mkswap_full_usage "\n\n" \ |
diff --git a/loginutils/Config.in b/loginutils/Config.in index 6efca7edf..ddd0c8015 100644 --- a/loginutils/Config.in +++ b/loginutils/Config.in | |||
| @@ -242,22 +242,16 @@ config CRYPTPW | |||
| 242 | bool "cryptpw" | 242 | bool "cryptpw" |
| 243 | default n | 243 | default n |
| 244 | help | 244 | help |
| 245 | Applet for crypting a string. | 245 | Encrypts the given password with the crypt(3) libc function |
| 246 | using the given salt. Debian has this utility under mkpasswd | ||
| 247 | name. Busybox provides mkpasswd as an alias for cryptpw. | ||
| 246 | 248 | ||
| 247 | config CHPASSWD | 249 | config CHPASSWD |
| 248 | bool "chpasswd" | 250 | bool "chpasswd" |
| 249 | default n | 251 | default n |
| 250 | help | 252 | help |
| 251 | chpasswd reads a file of user name and password pairs from | 253 | Reads a file of user name and password pairs from standard input |
| 252 | standard input and uses this information to update a group of | 254 | and uses this information to update a group of existing users. |
| 253 | existing users. | ||
| 254 | |||
| 255 | config MKPASSWD | ||
| 256 | bool "mkpasswd" | ||
| 257 | default n | ||
| 258 | help | ||
| 259 | mkpasswd encrypts the given password with the crypt(3) libc function | ||
| 260 | using the given salt. | ||
| 261 | 255 | ||
| 262 | config SU | 256 | config SU |
| 263 | bool "su" | 257 | bool "su" |
diff --git a/loginutils/Kbuild b/loginutils/Kbuild index 616d97721..3d0d777e8 100644 --- a/loginutils/Kbuild +++ b/loginutils/Kbuild | |||
| @@ -11,7 +11,6 @@ lib-$(CONFIG_CRYPTPW) += cryptpw.o | |||
| 11 | lib-$(CONFIG_CHPASSWD) += chpasswd.o | 11 | lib-$(CONFIG_CHPASSWD) += chpasswd.o |
| 12 | lib-$(CONFIG_GETTY) += getty.o | 12 | lib-$(CONFIG_GETTY) += getty.o |
| 13 | lib-$(CONFIG_LOGIN) += login.o | 13 | lib-$(CONFIG_LOGIN) += login.o |
| 14 | lib-$(CONFIG_MKPASSWD) += mkpasswd.o | ||
| 15 | lib-$(CONFIG_PASSWD) += passwd.o | 14 | lib-$(CONFIG_PASSWD) += passwd.o |
| 16 | lib-$(CONFIG_SU) += su.o | 15 | lib-$(CONFIG_SU) += su.o |
| 17 | lib-$(CONFIG_SULOGIN) += sulogin.o | 16 | lib-$(CONFIG_SULOGIN) += sulogin.o |
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 0c1a9a0db..c179e35cf 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
| @@ -3,75 +3,111 @@ | |||
| 3 | * cryptpw.c | 3 | * cryptpw.c |
| 4 | * | 4 | * |
| 5 | * Cooked from passwd.c by Thomas Lundquist <thomasez@zelow.no> | 5 | * Cooked from passwd.c by Thomas Lundquist <thomasez@zelow.no> |
| 6 | * mkpasswd compatible options added by Bernhard Reutner-Fischer | ||
| 6 | */ | 7 | */ |
| 7 | 8 | ||
| 8 | #include "libbb.h" | 9 | #include "libbb.h" |
| 9 | 10 | ||
| 10 | #define TESTING 0 | 11 | /* Debian has 'mkpasswd' utility, manpage says: |
| 11 | 12 | ||
| 12 | /* | 13 | NAME |
| 13 | set TESTING to 1 and pipe some file through this script | 14 | mkpasswd - Overfeatured front end to crypt(3) |
| 14 | if you played with bbox's crypt implementation. | 15 | SYNOPSIS |
| 16 | mkpasswd PASSWORD SALT | ||
| 17 | ... | ||
| 18 | OPTIONS | ||
| 19 | -S, --salt=STRING | ||
| 20 | Use the STRING as salt. It must not contain prefixes such as | ||
| 21 | $1$. | ||
| 22 | -R, --rounds=NUMBER | ||
| 23 | Use NUMBER rounds. This argument is ignored if the method | ||
| 24 | choosen does not support variable rounds. For the OpenBSD Blowfish | ||
| 25 | method this is the logarithm of the number of rounds. | ||
| 26 | -m, --method=TYPE | ||
| 27 | Compute the password using the TYPE method. If TYPE is 'help' | ||
| 28 | then the available methods are printed. | ||
| 29 | -P, --password-fd=NUM | ||
| 30 | Read the password from file descriptor NUM instead of using getpass(3). | ||
| 31 | If the file descriptor is not connected to a tty then | ||
| 32 | no other message than the hashed password is printed on stdout. | ||
| 33 | -s, --stdin | ||
| 34 | Like --password-fd=0. | ||
| 35 | ENVIRONMENT | ||
| 36 | $MKPASSWD_OPTIONS | ||
| 37 | A list of options which will be evaluated before the ones | ||
| 38 | specified on the command line. | ||
| 39 | BUGS | ||
| 40 | This programs suffers of a bad case of featuritis. | ||
| 41 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| 15 | 42 | ||
| 16 | while read line; do | 43 | Very true... |
| 17 | n=`./busybox cryptpw -a des -- "$line"` | 44 | |
| 18 | o=`./busybox_org cryptpw -a des -- "$line"` | 45 | cryptpw was in bbox before this gem, so we retain it, and alias mkpasswd |
| 19 | test "$n" != "$o" && { | 46 | to cryptpw. -a option (alias for -m) came from cryptpw. |
| 20 | echo n="$n" | 47 | */ |
| 21 | echo o="$o" | ||
| 22 | exit | ||
| 23 | } | ||
| 24 | n=`./busybox cryptpw -- "$line"` | ||
| 25 | o=`./busybox_org cryptpw -- "$line"` | ||
| 26 | test "$n" != "$o" && { | ||
| 27 | echo n="$n" | ||
| 28 | echo o="$o" | ||
| 29 | exit | ||
| 30 | } | ||
| 31 | done | ||
| 32 | */ | ||
| 33 | 48 | ||
| 34 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 49 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 35 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) | 50 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) |
| 36 | { | 51 | { |
| 37 | char salt[sizeof("$N$") + 16 + TESTING*100]; | 52 | /* $N$ + sha_salt_16_bytes + NUL */ |
| 38 | char *opt_a; | 53 | char salt[3 + 16 + 1]; |
| 39 | int opts; | 54 | char *salt_ptr; |
| 40 | 55 | const char *opt_m, *opt_S; | |
| 41 | opts = getopt32(argv, "a:", &opt_a); | 56 | int len; |
| 57 | int fd; | ||
| 42 | 58 | ||
| 43 | if (opts && opt_a[0] == 'd') { | 59 | #if ENABLE_GETOPT_LONG |
| 44 | crypt_make_salt(salt, 2/2, 0); /* des */ | 60 | static const char mkpasswd_longopts[] ALIGN1 = |
| 45 | #if TESTING | 61 | "stdin\0" No_argument "s" |
| 46 | strcpy(salt, "a."); | 62 | "password-fd\0" Required_argument "P" |
| 63 | "salt\0" Required_argument "S" | ||
| 64 | "method\0" Required_argument "m" | ||
| 65 | ; | ||
| 66 | applet_long_options = mkpasswd_longopts; | ||
| 47 | #endif | 67 | #endif |
| 48 | } else { | 68 | fd = STDIN_FILENO; |
| 49 | salt[0] = '$'; | 69 | opt_m = "d"; |
| 50 | salt[1] = '1'; | 70 | opt_S = NULL; |
| 51 | salt[2] = '$'; | 71 | /* at most two non-option arguments; -P NUM */ |
| 72 | opt_complementary = "?2:P+"; | ||
| 73 | getopt32(argv, "sP:S:m:a:", &fd, &opt_S, &opt_m, &opt_m); | ||
| 74 | argv += optind; | ||
| 75 | |||
| 76 | /* have no idea how to handle -s... */ | ||
| 77 | |||
| 78 | if (argv[0] && !opt_S) | ||
| 79 | opt_S = argv[1]; | ||
| 80 | |||
| 81 | len = 2/2; | ||
| 82 | salt_ptr = salt; | ||
| 83 | if (opt_m[0] != 'd') { /* not des */ | ||
| 84 | len = 8/2; /* so far assuming md5 */ | ||
| 85 | *salt_ptr++ = '$'; | ||
| 86 | *salt_ptr++ = '1'; | ||
| 87 | *salt_ptr++ = '$'; | ||
| 52 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA | 88 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA |
| 53 | if (opts && opt_a[0] == 's') { | 89 | if (opt_m[0] == 's') { /* sha */ |
| 54 | salt[1] = '5' + (strcmp(opt_a, "sha512") == 0); | 90 | salt[1] = '5' + (strcmp(opt_m, "sha512") == 0); |
| 55 | crypt_make_salt(salt + 3, 16/2, 0); /* sha */ | 91 | len = 16/2; |
| 56 | #if TESTING | ||
| 57 | strcpy(salt, "$5$rounds=5000$toolongsaltstring"); | ||
| 58 | // with "This is just a test" as password, should produce: | ||
| 59 | // "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8mGRcvxa5" | ||
| 60 | strcpy(salt, "$6$rounds=5000$toolongsaltstring"); | ||
| 61 | // with "This is just a test" as password, should produce: | ||
| 62 | // "$6$rounds=5000$toolongsaltstrin$lQ8jolhgVRVhY4b5pZKaysCLi0QBxGoNeKQzQ3glMhwllF7oGDZxUhx1yxdYcz/e1JSbq3y6JMxxl8audkUEm0" | ||
| 63 | #endif | ||
| 64 | } else | ||
| 65 | #endif | ||
| 66 | { | ||
| 67 | crypt_make_salt(salt + 3, 8/2, 0); /* md5 */ | ||
| 68 | #if TESTING | ||
| 69 | strcpy(salt + 3, "ajg./bcf"); | ||
| 70 | #endif | ||
| 71 | } | 92 | } |
| 93 | #endif | ||
| 72 | } | 94 | } |
| 95 | if (opt_S) | ||
| 96 | safe_strncpy(salt_ptr, opt_S, sizeof(salt) - 3); | ||
| 97 | else | ||
| 98 | crypt_make_salt(salt_ptr, len, 0); | ||
| 99 | |||
| 100 | xmove_fd(fd, STDIN_FILENO); | ||
| 73 | 101 | ||
| 74 | puts(pw_encrypt(argv[optind] ? argv[optind] : xmalloc_fgetline(stdin), salt, 1)); | 102 | puts(pw_encrypt( |
| 103 | argv[0] ? argv[0] : ( | ||
| 104 | /* Only mkpasswd, and only from tty, prompts. | ||
| 105 | * Otherwise it is a plain read. */ | ||
| 106 | (isatty(0) && applet_name[0] == 'm') | ||
| 107 | ? bb_ask(STDIN_FILENO, 0, "Password: ") | ||
| 108 | : xmalloc_fgetline(stdin) | ||
| 109 | ), | ||
| 110 | salt, 1)); | ||
| 75 | 111 | ||
| 76 | return 0; | 112 | return EXIT_SUCCESS; |
| 77 | } | 113 | } |
diff --git a/loginutils/mkpasswd.c b/loginutils/mkpasswd.c deleted file mode 100644 index 442738e03..000000000 --- a/loginutils/mkpasswd.c +++ /dev/null | |||
| @@ -1,71 +0,0 @@ | |||
| 1 | /* vi: set sw=4 ts=4 sts=4: */ | ||
| 2 | /* | ||
| 3 | * mkpasswd - Overfeatured front end to crypt(3) | ||
| 4 | * Copyright (c) 2008 Bernhard Reutner-Fischer | ||
| 5 | * | ||
| 6 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include "libbb.h" | ||
| 10 | |||
| 11 | int mkpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
| 12 | int mkpasswd_main(int argc UNUSED_PARAM, char **argv) | ||
| 13 | { | ||
| 14 | char *chp = NULL, *method = NULL, *salt = NULL; | ||
| 15 | char *encrypted; | ||
| 16 | int fd = STDIN_FILENO; | ||
| 17 | enum { | ||
| 18 | OPT_P = (1 << 0), | ||
| 19 | OPT_s = (1 << 1), | ||
| 20 | OPT_m = (1 << 2), | ||
| 21 | OPT_S = (1 << 3) | ||
| 22 | }; | ||
| 23 | static const char methods[] ALIGN1 = | ||
| 24 | /*"des\0"*/"md5\0""sha-256\0""sha-512\0"; | ||
| 25 | enum { TYPE_des, TYPE_md5, TYPE_sha256, TYPE_sha512 }; | ||
| 26 | unsigned algo = TYPE_des, algobits = 1; | ||
| 27 | #if ENABLE_GETOPT_LONG | ||
| 28 | static const char mkpasswd_longopts[] ALIGN1 = | ||
| 29 | "password-fd\0" Required_argument "P" | ||
| 30 | "stdin\0" No_argument "s" | ||
| 31 | "method\0" Required_argument "m" | ||
| 32 | "salt\0" Required_argument "S" | ||
| 33 | ; | ||
| 34 | applet_long_options = mkpasswd_longopts; | ||
| 35 | #endif | ||
| 36 | opt_complementary = "?1"; /* at most one non-option argument */ | ||
| 37 | getopt32(argv, "P:sm:S:", &chp, &method, &salt); | ||
| 38 | argv += optind; | ||
| 39 | if (option_mask32 & OPT_P) | ||
| 40 | fd = xatoi_u(chp); | ||
| 41 | if (option_mask32 & OPT_m) | ||
| 42 | algo = index_in_strings(methods, method) + 1; | ||
| 43 | if (*argv) /* we have a cleartext passwd */ | ||
| 44 | chp = *argv; | ||
| 45 | else | ||
| 46 | chp = bb_ask(fd, 0, "Password: "); | ||
| 47 | if (!salt) | ||
| 48 | salt = xmalloc(128); | ||
| 49 | |||
| 50 | if (algo) { | ||
| 51 | char foo[2]; | ||
| 52 | foo[0] = foo[2] = '$'; | ||
| 53 | algobits = 4; | ||
| 54 | /* MD5 == "$1$", SHA-256 == "$5$", SHA-512 == "$6$" */ | ||
| 55 | if (algo > 1) { | ||
| 56 | algo += 3; | ||
| 57 | algobits = 8; | ||
| 58 | } | ||
| 59 | foo[1] = '0' + (algo); | ||
| 60 | strcpy(salt, foo); | ||
| 61 | } | ||
| 62 | /* The opt_complementary adds a bit of additional noise, which is good | ||
| 63 | but not strictly needed. */ | ||
| 64 | crypt_make_salt(salt + ((!!algo) * 3), algobits, (int)&opt_complementary); | ||
| 65 | encrypted = pw_encrypt(chp, salt, 1); | ||
| 66 | puts(encrypted); | ||
| 67 | if (ENABLE_FEATURE_CLEAN_UP) { | ||
| 68 | free(encrypted); | ||
| 69 | } | ||
| 70 | return EXIT_SUCCESS; | ||
| 71 | } | ||
