# HG changeset patch # User Eris Caffee # Date 1311012284 18000 # Node ID 462ba4c70c6566d8e34ea245f43e70d2939ded83 # Parent 065d2beb69a574c54a2e3fc2d40a482f93a9d474 Eliminated global vars (undeclared variables suck). Added check for no username available. Cleanup up test code. diff -r 065d2beb69a5 -r 462ba4c70c65 make-username.pl --- a/make-username.pl Mon Jul 18 10:15:15 2011 -0500 +++ b/make-username.pl Mon Jul 18 13:04:44 2011 -0500 @@ -28,6 +28,8 @@ use English; use File::Basename; +# main is a block. NO GLOBALS! +{ my $base =""; my $user; my $debug = 0; @@ -56,99 +58,78 @@ } if (! $test) { - $user = make_username($base); - defined $user and printf("%s\n", $user); + $user = make_username($base, $maxlen); + if (defined $user) { + printf("%s\n", $user); + } else { + printf(STDERR "No username available\n"); + } exit 0; } else { my $pwdfile = "passwd"; - $base = ""; - my $t1 = time; - $user = make_username($base, $pwdfile); - my $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); + my ($base, $t1, $t2); + my @bases = ("", # should use default "user" as base. user and user1 taken + "eightchr", + "short", + "this *&% is not allowed &^$%&^m", + "123digits", + "this-is-a-domain.com", + '&$%#&$*&$%*&', + "testqwer", # testqwer taken + "testabc", # all testabc? taken + "testzx", # all testzx?? taken + "test", # all test??? taken + "t" # all z????? taken though 10435 + ); + + foreach $base (@bases) { + $t1 = time; + $user = make_username($base, $maxlen, $pwdfile); + $t2 = time; + if (defined $user) { + printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); + } else { + printf("%30s No username available\n", $base, $t2 - $t1); + } + } - $base = "eightchr"; + $maxlen = 2; + $base = "z"; # all z? taken. Should return no username. $t1 = time; - $user = make_username($base, $pwdfile); + $user = make_username($base, $maxlen, $pwdfile); $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); + if (defined $user) { + printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); + } else { + printf("%30s No username available\n", $base, $t2 - $t1); + } - $base = "short"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "this *&% is not allowed &^$%&^m"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); +} - $base = "123digits"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "this-is-a-domain.com"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = '&$%#&$*&$%*&'; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "testqwer"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "testabc"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "testzx"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "test"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); - - $base = "t"; - $t1 = time; - $user = make_username($base, $pwdfile); - $t2 = time; - defined $user and printf("%30s %-".$maxlen."s in %ds\n", $base, $user, $t2 - $t1); } +exit 0; ################################################################################ sub make_username { # Arguments: - # The string to use as the basis of the new username. - # Can be any string (such as an existing username or a domain name) - # But at most 8 characters will be used. Invalid characters will - # be removed. - # If the first character would be a number, an 'a' is prepended to the name. - # If blank, the string "user" will be used. + # $base The string to use as the basis of the new username. + # Can be any string (such as an existing username or a domain name) + # But at most $maxlen characters will be used. Invalid characters will + # be removed. + # If the first character would be a number, an 'a' is prepended to the name. + # If blank, the string "user" will be used. + # $maxlen The maximum length of the username to create. If not specified, + # it defaults to 8. It must be 2 or more. (If it was 1 then there + # would be no way to prepend a number to it without having a digit as + # the first character of the new name.) + # $pwdfile The name of the passwd file to use for checking for new users. + # /etc/passwd by default. This is really a debugging option. # # Returns: # A string containing the new username or undef if no username # could be generated (unlikely) - my ($base, $pwdfile) = @_; + my ($base, $maxlen, $pwdfile) = @_; if ($base eq "") { $base = "user"; @@ -156,6 +137,15 @@ ! defined $pwdfile and $pwdfile = "/etc/passwd"; + if (! defined $maxlen) { + $maxlen = 8; + } else { + if ($maxlen !~ /^\d+$/) { + printf(STDERR "Error: non-numeric username length specified.\n"); + return undef; + } + } + if (! -e $pwdfile) { printf(STDERR "Error: non-existant passwd file specified: $pwdfile\n"); return undef; @@ -169,27 +159,27 @@ } # Use the specified parameter as the base of the new username. - # Print it into a string of exactly 8 characters. + # Print it into a string of exactly $maxlen characters. # Print the number into the last portion of the new username. # Delete spaces (in case the passed username candidate was short). # Churn until we find an unused name. - my $tries=0; my $i=1; my $numstr; my $newuser = sprintf("%.".$maxlen."s", $base); - - while ( (user_exists($newuser, $pwdfile)) && ($i < 10000000) ) { - $tries = 1; + # print "maxlen $maxlen\n"; + #print "newuser +$newuser+\n"; + while ( (user_exists($newuser, $pwdfile)) && ($i < 10**($maxlen-1)) ) { $numstr = sprintf("%d", $i); $newuser = sprintf("%-".$maxlen."s", $base); +# print "1 newuser $newuser\n"; substr($newuser, -length($numstr), length($numstr), $numstr); + # print "2 newuser $newuser\n"; $newuser =~ s/ //g; + # print "3 newuser $newuser\n"; $i++; - $debug and printf(STDERR "Checking for $newuser\n"); } - $i == 10000000 and return undef; - $debug and print "final is $newuser in $tries attempts\n"; + $i >= 10**($maxlen-1) and return undef; return $newuser; } diff -r 065d2beb69a5 -r 462ba4c70c65 passwd-huge.gz Binary file passwd-huge.gz has changed