view make-username.pl @ 4:742a3d2c99d6

Removed commented code and timing notes left from I/O testing.
author Eris Caffee <discordia@eldalin.com>
date Mon, 18 Jul 2011 07:13:12 -0500
parents 706c20861682
children 0979af167267
line source
1 #!/usr/bin/env perl
3 use warnings;
4 use strict;
5 use English;
6 use File::Basename;
8 my $base ="";
9 my $user;
10 my $debug = 0;
11 my $maxlen = 8;
12 my $test = 0;
14 foreach my $arg (@ARGV) {
15 if ("-d" eq $arg) {
16 $debug = 1;
17 } elsif ($arg =~ /^-m/) {
18 $arg =~ s/^..//;
19 if ($arg =~ /^(\d+)$/) {
20 $maxlen = $1;
21 $debug and print "Setting maxlen to $maxlen\n";
22 } else {
23 printf(STDERR "Invalid username length specified: $arg\n");
24 }
25 } elsif ($arg eq "-h") {
26 usage();
27 exit 0;
28 } elsif ($arg eq "-t") {
29 $test = 1;
30 } else {
31 $base = $arg;
32 }
33 }
35 if (! $test) {
36 $user = make_username($base);
37 defined $user and printf("%s\n", $user);
38 exit 0;
39 } else {
40 my $pwdfile = "passwd";
41 $base = "";
42 $user = make_username($base, $pwdfile);
43 defined $user and printf("%30s %s\n", $base, $user);
45 $base = "eightchr";
46 $user = make_username($base, $pwdfile);
47 defined $user and printf("%30s %s\n", $base, $user);
49 $base = "short";
50 $user = make_username($base, $pwdfile);
51 defined $user and printf("%30s %s\n", $base, $user);
53 $base = "this *&% is not allowed &^$%&^m";
54 $user = make_username($base, $pwdfile);
55 defined $user and printf("%30s %s\n", $base, $user);
57 $base = "123digits";
58 $user = make_username($base, $pwdfile);
59 defined $user and printf("%30s %s\n", $base, $user);
61 $base = "this-is-a-domain.com";
62 $user = make_username($base, $pwdfile);
63 defined $user and printf("%30s %s\n", $base, $user);
65 $base = '&$%#&$*&$%*&';
66 $user = make_username($base, $pwdfile);
67 defined $user and printf("%30s %s\n", $base, $user);
69 $base = "testqwer";
70 $user = make_username($base, $pwdfile);
71 defined $user and printf("%30s %s\n", $base, $user);
73 $base = "testabc";
74 $user = make_username($base, $pwdfile);
75 defined $user and printf("%30s %s\n", $base, $user);
77 $base = "testzx";
78 $user = make_username($base, $pwdfile);
79 defined $user and printf("%30s %s\n", $base, $user);
81 $base = "test";
82 $user = make_username($base, $pwdfile);
83 defined $user and printf("%30s %s\n", $base, $user);
85 $base = "t";
86 $user = make_username($base, $pwdfile);
87 defined $user and printf("%30s %s\n", $base, $user);
88 }
90 sub make_username {
91 # Arguments:
92 # The string to use as the basis of the new username.
93 # Can be any string (such as an existing username or a domain name)
94 # But at most 8 characters will be used. Invalid characters will
95 # be removed.
96 # If the first character would be a number, an 'a' is prepended to the name.
97 # If blank, the string "user" will be used.
98 #
99 # Returns:
100 # A string containing the new username or undef if no username
101 # could be generated (unlikely)
103 my ($base, $pwdfile) = @_;
105 if ($base eq "") {
106 $base = "user";
107 }
109 ! defined $pwdfile and $pwdfile = "/etc/passwd";
111 if (! -e $pwdfile) {
112 printf(STDERR "Error: non-existant passwd file specified: $pwdfile\n");
113 return undef;
114 }
116 # Remove non-alpha-numeric characters and make sure the first character is a letter.
117 $base =~ s/[^A-Za-z0-9]//g;
118 if ($base !~ /^[a-z]/ ) {
119 $base = "a".$base;
120 }
122 # Use the specified parameter as the base of the new username.
123 # Print it into a string of exactly 8 characters.
124 # Print the number into the last portion of the new username.
125 # Delete spaces (in case the passed username candidate was short).
126 # Churn until we find an unused name.
127 my $tries=0;
128 my $i=1;
129 my $numstr;
130 my $newuser = sprintf("%.".$maxlen."s", $base);
132 while ( (! system('grep -qsP "^'.$newuser.':" '.$pwdfile)) &&
133 ($i < 10000000) ) {
134 $tries = 1;
135 $numstr = sprintf("%d", $i);
136 $newuser = sprintf("%-".$maxlen."s", $base);
137 substr($newuser, -length($numstr), length($numstr), $numstr);
138 $newuser =~ s/ //g;
139 $i++;
140 }
142 $i == 10000000 && return undef;
143 $debug and print "final is $newuser in $tries attempts\n";
144 return $newuser;
145 }
148 ################################################################################
149 sub usage {
150 printf(
151 "Usage: ".basename($PROGRAM_NAME)." [-h] [-d] [-mM] [-t] [basename]
153 Generate a new unused username suitable for assigning to a new account.
155 basename If specified this will be used as the basis of the new username
157 The basename will be stripped of all characters other than letters
158 and digits, and it will be truncated to no more than the maximum
159 allowed username length (8 by default, but settable with the
160 -m option).
161 In the event that a user already exists by the given name a number
162 will be inserted at the end of the username and sequentially
163 increased until an available name is found.
164 If basename is not specified, then \"user\" will be used as the base.
165 -h Print these instructions.
166 -d Enable debug messages.
167 -mM Set maximum allowed username length to M (default is 8).
168 -t Perform test code. You must have a suitable passwd file in the
169 current directory in order to run this.
170 ");
171 }