123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- #!/usr/bin/perl
- #
- # add_user
- #
- # Add one or more users to the XML directory
- #
- #
- use strict;
- use warnings;
- use Getopt::Long;
- use Data::Dumper;
- ## Useful items
- my $path_sep;
- my $config_path;
- my @dir_elem;
- my $user_template = &get_user_template;
- my $new_user_count = 0;
- ## Command line args
- my $users;
- my $domain;
- my $dirpath;
- my $help;
- ## Misc items somewhat related to cmd line args
- my $start;
- my $end;
- my $user;
- ## Check for Windows vs. *nix
- if ( $^O =~ m/^win/i ) {
- ## Detected Windows (probably)
- $path_sep = "\\"; # single backslash (\)
- use File::Spec::Win32;
- } else {
- $path_sep = '/'; # single slash (/)
- use File::Spec;
- }
- GetOptions(
- 'h' => \$help,
- 'help' => \$help,
- 'domain=s' => \$domain,
- 'users=s' => \$users,
- 'confpath=s' => \$config_path,
- );
- if ( $help ) {
- usage();
- exit(0);
- }
- if ( ! $domain ) {
- $domain='default';
- }
- ## Validate users if specified on command line
- if ( $users ) {
- ($start,$end) = split /-/,$users;
- if ( ! $start && ! $end ) {
- die "Please specify both a start and end range, separated by a hyphen:\n add_user --users=xxxx-yyyy\n";
- }
- unless ( $start =~ m/[1-9]\d+/ ) {
- die "Start of range '$start' is not numeric or is too short\n";
- }
- unless ( $end =~ m/[1-9]\d+/ ) {
- die "End of range '$end' is not numberic or is too short\n";
- }
- if ( $end <= $start ) {
- die "End of range needs to be greater than start of range\n";
- }
- } else {
- ## Look for user id in $ARGV[0]
- if ( ! $ARGV[0] ) {
- die "You must specify user id as a command line argument to add user, or use the --users option.\n";
- }
- unless ( $ARGV[0] =~ m/^[1-9]\d+$/ ) {
- die "User id must be numeric, be at least 2 digits long, and cannot begin with the digit zero.\n"
- }
- $user = $ARGV[0];
- }
- if ( ! $config_path ) {
- $config_path = '/usr/local/freeswitch/conf';
- }
- ## Check to make sure the directories in question exists
- unless ( -d $config_path ) {
- die "Configuration path '$config_path' does not exist.\n";
- }
- my $directory_path = $config_path . $path_sep . 'directory';
- unless ( -d $directory_path ) {
- die "Directory path '$directory_path' does not exist.\n";
- }
- ## Now check domain pathname and test existence
- if ( ! $domain ) {
- $domain = 'default';
- }
- ## Full directory path includes the domain name
- my $full_dir_path = $directory_path . $path_sep . $domain;
- unless ( -d $full_dir_path ) {
- die "Full path to directory and domain '$full_dir_path' does not exist. \n";
- }
- unless ( -w $full_dir_path ) {
- die "This user does not have write access to '$full_dir_path'.\n";
- }
- print "\n";
- ## Regexp assemble items to show user what a PCRE might look like for his new users
- my $ra_present;
- my $ra_new;
- my $ra_all;
- eval { require Regexp::Assemble; };
- if ( ! $@ ) {
- ## If Regexp::Assemble is available flag it for later building regexes
- $ra_present = 'true';
- $ra_new = Regexp::Assemble->new( # new user regex
- reduce => 1,
- flags => 0,
- );
- $ra_all = Regexp::Assemble->new( # all users regex w/ new users thrown in
- reduce => 1,
- flags => 0,
- );
- }
- ## If we're this far then we can read in the existing users and put them in a hash
- ## Later we can check hash to avoid adding duplicate users
- my %current_users;
- my @CURRENT_USER_FILES = glob($full_dir_path . $path_sep . '*.xml');
- foreach ( @CURRENT_USER_FILES ) {
- #print "User: $_\n";
- open(FILEIN,'<',$_);
- while(<FILEIN>) {
- next unless m/user id|number-alias/;
- m/user id="(\d+)"/;
- my $user_id = $1;
- if ( ! $user_id ) {
- m/alias="(\d+)"/;
- $user_id = $1;
- }
- next unless $user_id;
- $current_users{$user_id}++;
- if ( $ra_present && $user_id =~ m/^\d+$/ ) {
- #print "Adding $user_id to \$re_all...\n";
- $ra_all->add($user_id)->anchor_line_begin->anchor_line_end;
- }
- last;
- }
- close(FILEIN);
- }
- #print Dumper(%current_users) . "\n";
- if ( $start && $end ) {
- ## Add range of users
- foreach $user ($start .. $end) {
- &add_user($user);
- }
- } else {
- ## Add single user
- &add_user($user);
- }
- print "\nOperation complete. ";
- if ( $new_user_count == 0 ) {
- print "No users added.\n";
- exit(0);
- } else {
- printf "%d user%s added.\n", $new_user_count, $new_user_count==1 ? "" : "s";
- print "Be sure to reloadxml.\n\n";
- }
- if ( $ra_present ) {
- print "Regular expression information:\n\n";
- ## Regexp::Assemble adds some stuff we really don't need
- ## These lines just make the regexp pattern a bit more readable
- my $tmp = $ra_new->as_string;
- $tmp =~ s/\?://g;
- $tmp =~ s/^\(\?\-xism:\^/^(/;
- $tmp =~ s/\$\)$/)\$/;
- $tmp =~ s/\\d/[0-9]/g; # [0-9] is sometimes easier to read than \d
- print " Sample regex for all new users: " . $tmp . "\n";
- $tmp = $ra_all->as_string;
- $tmp =~ s/\?://g;
- $tmp =~ s/^\(\?\-xism:\^/^(/;
- $tmp =~ s/\$\)$/)\$/;
- $tmp =~ s/\\d/[0-9]/g; # [0-9] is sometimes easier to read than \d
- print "Sample regex for all new AND current users: " . $tmp . "\n\n";
- print "In the default configuration you can modify the expression in the condition for 'Local_Extension'.\n";
- print ""
- } else {
- print "If CPAN module Regexp::Assemble were installed this program would be able to suggest a regex for your new users.\n"
- }
- exit(0);
- sub add_user {
- my $user_id = shift;
- if ( exists( $current_users{$user_id} ) ) {
- warn "User id $user_id already exists, skipping...\n";
- } else {
- my $new_user = $user_template;
- $new_user =~ s/__USERID__/$user_id/g;
- #print "Adding user id '$user_id' with this XML:\n";
- #print $new_user . "\n";
- ## Attempt to create the user file
- my $user_file_name = $full_dir_path . $path_sep . $user_id . '.xml';
- ## Does it already exist?
- if ( -f $user_file_name ) {
- warn "$user_file_name exists, skipping...\n";
- }
- my $fh;
- open($fh,'>',$user_file_name);
- if ( ! $fh ) {
- warn "Unable to open '$user_file_name' - $!\n";
- warn "Skipping...\n";
- next;
- }
- print $fh $new_user;
- close($fh);
- print "Added $user_id in file $user_file_name \n";
- $new_user_count++;
- if ( $ra_present ) {
- $ra_new->add($user_id)->anchor_line_begin->anchor_line_end;
- $ra_all->add($user_id)->anchor_line_begin->anchor_line_end;
- }
- }
- }
- sub get_user_template {
- my $templ = <<ENDUSERTEMPLATE;
- <include>
- <user id="__USERID__">
- <params>
- <param name="password" value="\$\${default_password}"/>
- <param name="vm-password" value="__USERID__"/>
- </params>
- <variables>
- <variable name="toll_allow" value="domestic,international,local"/>
- <variable name="accountcode" value="__USERID__"/>
- <variable name="user_context" value="default"/>
- <variable name="effective_caller_id_name" value="Extension __USERID__"/>
- <variable name="effective_caller_id_number" value="__USERID__"/>
- <variable name="outbound_caller_id_name" value="\$\${outbound_caller_name}"/>
- <variable name="outbound_caller_id_number" value="\$\${outbound_caller_id}"/>
- <variable name="callgroup" value="techsupport"/>
- </variables>
- </user>
- </include>
- ENDUSERTEMPLATE
- return $templ;
- }
- sub usage {
- print <<ENDUSAGE;
- FreeSWITCH add user utility
- Adds one or more users to the FreeSWITCH directory using XML files.
- Syntax:
- add_user <user_id> [--domain=<domain_name>] [--confpath=<configuration_path>]
- add_user --users=<start_user_id>-<end_user_id> [--domain=<domain_name>] [--confpath=<configuration_path>]
- In its simplest form, add_user will simply add the user_id specified at the command line.
- By default, users are added to the "default" domain. Use the --domain option to specify
- a different domain for the user(s) that are added.
- To specify a range of user IDs use the --users option. Separate the beginning and
- end of the range with a hyphen (-) character.
- By default add_user will look for the XML directory in its default location of
- /usr/local/freeswitch/conf/directory. Use the --confpath (configuration path)
- option to specify an alternate directory location.
- NOTES:
- add_user assumes
- User IDs must be numeric and cannot begin with zero.
- User IDs must be at least two digits long and have no specific length limit.
- If a user ID exists it will be skipped.
- If a domain specified does not exist no users will be created.
- ENDUSAGE
- }
|