list all mailboxes / email addresses defined on server?

hostricity

Active Member
Jun 22, 2004
39
0
156
Does anyone know of a way to display a list of all mailboxes and all forwarders defined on a cpanel server (for all of the accounts)?
 

cPanelDavidG

Technical Product Specialist
Nov 29, 2006
11,216
13
313
Houston, TX
cPanel Access Level
Root Administrator
You can use the XML API to list all accounts on the server. Then you can use the API2 function calls via the XML API, looping through each account, using the following API2 functions: Cpanel::Email::listforwards (lists all email forwarders for an account) and Cpanel::Email::listpopswithdisk (lists all email accounts that are assigned disk space, e.g. webmail/pop/imap accounts).

You can find documentation for all of this at http://cpanel.net/plugins/devel
 

TheIdeaMan

Member
Apr 25, 2005
9
0
151
The XML API is great, btw. I've been working with it in PHP 5 with SimpleXML. It is much easier than the old Accounting system.

One question I still have, though, is how to find a list of the old API 1 calls. I'm trying to setup a script to integrate into another product that displays all the current e-mail boxes for a specific domain name, and allow users to create new ones via a form similar to the one in cPanel.

The addpop example on the cPanel XML API page works, but there doesn't seem to be a way to add a quota.

Is there API documentation for API 1 calls? or is there an equivalent 'addpop' function in API 2? I've not been able to find one, and my "guesses" haven't yet been successful.

Much appreciated in advance.
 

cPanelDavidG

Technical Product Specialist
Nov 29, 2006
11,216
13
313
Houston, TX
cPanel Access Level
Root Administrator
The XML API is great, btw. I've been working with it in PHP 5 with SimpleXML. It is much easier than the old Accounting system.

One question I still have, though, is how to find a list of the old API 1 calls. I'm trying to setup a script to integrate into another product that displays all the current e-mail boxes for a specific domain name, and allow users to create new ones via a form similar to the one in cPanel.

The addpop example on the cPanel XML API page works, but there doesn't seem to be a way to add a quota.

Is there API documentation for API 1 calls? or is there an equivalent 'addpop' function in API 2? I've not been able to find one, and my "guesses" haven't yet been successful.

Much appreciated in advance.
A nifty trick I use to find undocumented API2 functionality is to login via SSH and look at the theme files for X3 in /usr/local/cpanel/base/frontend/x3. The themes integrate with the cPanel source code using mostly API2 function calls (though some API 1 calls remain).

In the cPanel interface, when you go to create a POP3/IMAP/Webmail account with a quota, you are looking at: frontend/x3/mail/pops.html. So my trick is to look at the code for /usr/local/cpanel/base/frontend/x3/mail/pops.html. It seems the form posts to doaddpop.html but that page just includes doaddpopinclude.html for actually creating the account. Looking at that page, you will see:

HTML:
<cpanel Email="addpop($FORM{'email'},$FORM{'password'},$FORM{'quota'},$FORM{'domain'})">
That's an API 1 function (note the lack of :: operators), but that is what's used to create an email account by the X3 theme.
 

Grzeslaw

Well-Known Member
Jul 11, 2006
76
1
158
Poland
hehe, some time ago, I need to list all resseler mail accounts, so I wrote a simple bash script which list all resselers mail accoutnts witch their usernames:
Code:
#!/bin/bash

[email protected]
KONTA=`ls -1A /var/cpanel/users/`

count=1
for x in `echo -n "$KONTA"`;do
  wiersz=`grep -i ^dns /var/cpanel/users/"$x" |cut -d= -f2`
  DOMAIN[$count]=$wiersz
  count=$[$count+1]
  echo "Login:        `echo "$x"`"


    for i in `echo "${DOMAIN[@]}" | sed  's/ /\n/g'`;do
      for n in ` ls -A /home/"$x"/mail/"$i"/ 2>/dev/null`;do

           if   [ "$n" == "cur" ];then echo "$n" > /dev/null
           elif [ "$n" == "new" ];then echo "$n" > /dev/null
           elif [ "$n" == "tmp" ];then echo "$n" > /dev/null
           elif [ "$n" == "" ];then echo "$n" > /dev/null
           else
           echo  "$n"@"$i"
           fi
      done
    done
    echo;echo;
done
If this could help to anyone I'll be glad, but i warn that is very simple script and it's not 2fast ;-)

Usage:
# ./scriptname resselername

Regards
 
  • Like
Reactions: oviliz

TheIdeaMan

Member
Apr 25, 2005
9
0
151
Thanks, cPanelDavidG. That was exactly what I needed.

I look forward to API 2 having all the features. :)

Thanks again for the help.
 

nosajix

Well-Known Member
Jul 30, 2005
66
4
158
I don't really understand bash, I know I probably should but that being said, is there another way to do this? maybe with php? I know php cant really retrieve all of the domain home directories but Id be willing to feed it an array for that. What I would love is something that would collect all of the email addresses & forwarders that are setup in all of my cpanels. I set them all up so its not a question of privacy, I am the only one with cpanel access.
 

cPanelTristan

Quality Assurance Analyst
Staff member
Oct 2, 2010
7,607
40
248
somewhere over the rainbow
cPanel Access Level
Root Administrator
Whether understanding bash or not, you could still utilize the script previously provided in root SSH and simply save that file, then run the command. Or, are you speaking about the API options? The API does allow perl and PHP-based scripts to be used.
 

nosajix

Well-Known Member
Jul 30, 2005
66
4
158
I would definitely prefer api as in the end this information would be stored in a mysql database.
 

Secmas

Well-Known Member
Feb 18, 2005
358
10
168
@Grzeslaw,
this script was wrote back in 2008 and it still works, great job!!!

Thanks a lot for sharing.

Sergio
 

Erik Knepfler

Member
Sep 2, 2014
19
1
53
Long Beach, California, United States
cPanel Access Level
Root Administrator
hehe, some time ago, I need to list all resseler mail accounts, so I wrote a simple bash script
Thanks Grzeslaw. I ran your script and it worked, but it did take a while to run (~10 seconds). Also I wasn't sure about the relationship between the DNS= strings in the user files vs. the user folders (I'm sure it's fine, but I had already started working on my own version) so I just finished this slightly different approach in Perl, which it turned out is also MUCH faster to run.

Code:
use strict;
opendir(USERS, '/var/cpanel/users') || die $!;
while (my $user = readdir(USERS)) {
   # user loop
   next if $user =~ /^\./; # skip . and .. dirs
   opendir(ETC, "/home/$user/etc") || die $! . "/home/$user/etc";
   while (my $domain = readdir(ETC)) {
      next if $domain =~ /^\./; # skip . and .. dirs
      if (-d "/home/$user/etc/$domain/") {
         open(PASSWD, "/home/$user/etc/$domain/passwd") || die $! . "/home/$user/etc/$domain/passwd";
         while (my $PWLINE = <PASSWD>) {
            $PWLINE =~ s/:.*//; # only show line data before first colon (username only)
            print "$user,$domain," . $PWLINE . "";
         }
         close(PASSWD);
      }
   }
   closedir(ETC);
}
closedir(USERS);
This takes a fraction of a second to run.
It outputs in a CSV format with user,domain,account
It uses the files in /var/cpanel/users as a basis to start from, assuming each one will have a matching /home/$user
It then enumerates all files & directories in /home/$user/etc
It then considers each one that is actually a directory (the if (-d) line)
It then assumes it will find a passwd file inside each of those which it always does on mine. If it doesn't (i.e., you have custom folders in there) it might error and need slight tweaking.
It then looks in the passwd file at the username part behind the colon, and then outputs a CSV line.

Hope this helps!
 

petersphilo

Member
Nov 14, 2016
22
6
3
Paris
cPanel Access Level
Reseller Owner
@Erik Knepfler: thank you so much for your script, it really helped me!

i did tweak it for my needs, so that is returns the following fields, tab-separated:
user, email address, mailbox size (unit: MB)

here it is:
Code:
opendir(USERS, '/var/cpanel/users') || die $!;
while (my $user = readdir(USERS)) {
    # user loop
    next if $user =~ /^\.|system/; # skip . and .. and system dirs
    if (opendir(ETC, "/home/$user/etc")) {
    while (my $domain = readdir(ETC)) {
        next if $domain =~ /^\./; # skip . and .. dirs
        if (-d "/home/$user/etc/$domain/") {
             if (opendir(MAIL, "/home/$user/mail/$domain/")) {
             while (my $email = readdir(MAIL)) {
                next if $email =~ /^\./;
                if (-d "/home/$user/mail/$domain/$email/") {
                print "$user    $email\@$domain    ";
                system("du -BM --max-depth=0 /home/$user/mail/$domain/$email/ | cut -f1");
                }
                }
        }
        closedir(MAIL); }
    }
    closedir(ETC); }
}
closedir(USERS);
Thank you very much!
i hope this helps someone, and i'm sorry for reviving this old thread...
 
  • Like
Reactions: cPanelMichael