0
     	�_’I|¥‰ÓMjqØ‚¦ð¬÷ÂÁ      	File not found.
     �¾ÂÁ      File not found.
  "   ˆl–äY>”ÊC]Šq@¹p,Üh
bÑ¿Åƒ|N‡ÃÂ $7    #!/usr/bin/python3
# -*- python-mode -*-
'''
    Copyright (C) 2020
    Authors:    Achilles Gaikwad <agaikwad@redhat.com>
                Kenneth  D'souza <kdsouza@redhat.com>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
'''

import multiprocessing as mp
import os
import signal
import sys

try:
    import argparse
except ImportError:
    print('%s:  Failed to import argparse - make sure argparse is installed!'
        % sys.argv[0])
    sys.exit(1)
try:
    import yaml
except ImportError:
    print('%s:  Failed to import yaml - make sure python3-pyyaml is installed!'
        % sys.argv[0])
    sys.exit(1)

BBOLD = '\033[1;30;47m' #Bold black text with white background.
ENDC = '\033[m' #Rest to defaults

def init_worker():
    signal.signal(signal.SIGINT, signal.SIG_IGN)

# this function converts the info file to a dictionary format, sorta. 
def file_to_dict(path):
    client_info = {}
    try:
        with open(path) as f:
            for line in f:
                try:
                    (key, val) = line.split(':', 1)
                    client_info[key] = val.strip()
                    # FIXME: There has to be a better way of converting the info file to a dictionary.
                except ValueError as reason:
                    if verbose:
                        print('Exception occured, %s' % reason)

        if len(client_info) == 0 and verbose:
            print("Provided %s file is not valid" %path)
        return client_info

    except OSError as reason:
        if verbose:
            print('%s' % reason)

# this function gets the paths from /proc/fs/nfsd/clients/
# returns a list of paths for each client which has nfs-share mounted.
def getpaths():
    path = []
    try:
        dirs = os.listdir('/proc/fs/nfsd/clients/')
    except OSError as reason:
        exit('%s' % reason)
    if len(dirs) !=0:
	    for i in dirs:
                path.append('/proc/fs/nfsd/clients/' + i + '/states')
	    return (path)
    else:
        exit('Nothing to process')

# A single function to rule them all, in this function we gather all the data
# from already populated data_list and client_info.
def printer(data_list, argument):
    client_info_path = data_list.pop()
    client_info = file_to_dict(client_info_path)
    for i in data_list:
        for key in i:
            inode = i[key]['superblock'].split(':')[-1]
            # The ip address is quoted, so we dequote it.
            try:
                client_ip = client_info['address'][1:-1]
            except:
                client_ip = "N/A"
            try:
                # if the nfs-server reboots while the nfs-client holds the files open,
                # the nfs-server would print the filename as '/'. For such instaces we
                # print the output as disconnected dentry instead of '/'.
                if(i[key]['filename']=='/'):
                    fname = 'disconnected dentry'
                else:
                    fname = i[key]['filename'].split('/')[-1]
            except KeyError:
                # for older kernels which do not have the fname patch in kernel, they
                # won't be able to see the fname field. Therefore post it as N/A.
                fname = "N/A"
            otype = i[key]['type']
            try:
                access = i[key]['access']
            except:
        