<commit_before>/*
  Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
  This file is part of GlusterFS.

  GlusterFS 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.

  GlusterFS 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
  <http://www.gnu.org/licenses/>.
*/


#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif

#include "xlator.h"
#include "glusterfs.h"
#include "compat-errno.h"

#include "glusterd.h"
#include "glusterd-utils.h"

#include "portmap.h"
#include "protocol-common.h"
#include "rpcsvc.h"

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>


int
pmap_port_isfree (int port)
{
        struct sockaddr_in sin;
        int                sock = -1;
        int                ret = 0;

        memset (&sin, 0, sizeof (sin));
        sin.sin_family = PF_INET;
        sin.sin_port = hton16 (port);

        sock = socket (PF_INET, SOCK_STREAM, 0);
        if (sock == -1)
                return -1;

        ret = bind (sock, (struct sockaddr *)&sin, sizeof (sin));
        close (sock);

        return ret == 0 ? 1 : 0;
}


struct pmap_registry *
pmap_registry_new (void)
{
        struct pmap_registry *pmap = NULL;
        int                   i = 0;

        pmap = CALLOC (sizeof (*pmap), 1);
        if (!pmap)
                return NULL;

        for (i = 0; i < 65536; i++) {
                if (!pmap_port_isfree (i))
                        pmap->ports[i].used = 1;
        }

        pmap->base_port = 6969;
        pmap->last_alloc = 6969;

        return pmap;
}


struct pmap_registry *
pmap_registry_get (xlator_t *this)
{
        glusterd_conf_t      *priv = NULL;
        struct pmap_registry *pmap = NULL;

        priv = this->private;

        pmap = priv->pmap;
        if (!pmap) {
                pmap = pmap_registry_new ();
                if (!pmap)
                        return NULL;
                priv->pmap = pmap;
        }

        return pmap;
}


int
pmap_registry_search (xlator_t *this, const char *brickname)
{
        glusterd_conf_t      *priv = NULL;
        struct pmap_registry *pmap = NULL;
        int                   p = 0;
        int                   port = 0;

        priv = this->private;

        pmap = priv->pmap;

        for (p = pmap->base_port; p < 65535; p++) {
                if (strcmp (pmap->ports[p].brickname, brickname) == 0) {
                        port = p;
                        break;
                }
        }

        return port;
}


int
pmap_registry_alloc (xlator_t *this)
{
        glusterd_conf_t      *priv = NULL;
        struct pmap_registry *pmap = NULL;
        int                   p = 0;
        int                   port = 0;

        priv = this->private;

        pmap = priv->pmap;

        for (p = pmap->base_port; p < 65535; p++) {
                if (pmap->ports[p].used)
                        continue;

                if (pmap_port_isfree (p)) {
                        pmap->ports[p].used = 1;
                        port = p;
                        break;
                }
        }

        return port;
}



int
pmap_registry_bind (xlator_t *this, int port, const char *brickname)
{
        glusterd_conf_t      *priv = NULL;
        struct pmap_registry *pmap = NULL;
        int                   p = 0;


        priv = this->private;

        pmap = priv->pmap;

        pmap->ports[p].used = 1;
        if (pmap->ports[p].brickname)
                free (pmap->ports[p].brickname);
        pmap->ports[p].brickname = strdup (brickname);

        return 0;
}


typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data);


static int
xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc)
{
        int                     ret = -1;

        if (!req)
                return -1;

        ret = sfunc (req->msg[0], arg);

        if (ret > 0)
                ret = 0;<commit_msg>portmap: crash fix while getting registry pointer<commit_after>/*
  Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com>
  This file is part of GlusterFS.

  GlusterFS 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.

  GlusterFS 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
  <http://www.gnu.org/licenses/>.
*/


#ifndef _CONFIG_H
#define _CONFIG_H
#include "config.h"
#endif

#include "xlator.h"
#include "glusterfs.h"
#include "compat-errno.h"

#include "glusterd.h"
#include "glusterd-utils.h"

#include "portmap.h"
#include "protocol-common.h"
#include "rpcsvc.h"

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>


int
pmap_port_isfree (int port)
{
        struct sockaddr_in sin;
        int                sock = -1;
        int                ret = 0;

        memset (&sin, 0, sizeof (sin));
        sin.sin_family = PF_INET;
        sin.sin_port = hton16 (port);

        sock = socket (PF_INET, SOCK_STREAM, 0);
        if (sock == -1)
                return -1;

        ret = bind (sock, (struct sockaddr *)&sin, sizeof (sin));
        close (sock);

        return ret == 0 ? 1 : 0;
}


struct pmap_registry *
pmap_registry_new (void)
{
        struct pmap_registry *pmap = NULL;
        int                   i = 0;

        pmap = CALLOC (sizeof (*pmap), 1);
        if (!pmap)
                return NULL;

        for (i = 0; i < 65536; i++) {
                if (!pmap_port_isfree (i))
                        pmap->ports[i].used = 1;
        }

        pmap->base_port = 6969;
        pmap->last_alloc = 6969;

        return pmap;
}


struct pmap_registry *
pmap_registry_get (xlator_t *this)
{
        glusterd_conf_t      *priv = NULL;
        struct pmap_registry *pmap = NULL;

        priv = this->private;

        pmap = priv->pmap;
        if (!pmap) {
                pmap = pmap_registry_new ();
                if (!pmap)
                        return NULL;
                priv->pmap = pmap;
        }

        return pmap;
}


int
pmap_registry_search (xlator_t *this, const char *brickname)
{
        struct pmap_registry *pmap = NULL;
        int                   p = 0;
        int                   port = 0;

        pmap = pmap_registry_get (this);

        for (p = pmap->base_port; p < 65535; p++) {
                if (strcmp (pmap->ports[p].brickname, brickname) == 0) {
                        port = p;
                        break;
                }
        }

        return port;
}


int
pmap_registry_alloc (xlator_t *this)
{
        struct pmap_registry *pmap = NULL;
        int                   p = 0;
        int                   port = 0;

        pmap = pmap_registry_get (this);

        for (p = pmap->base_port; p < 65535; p++) {
                if (pmap->ports[p].used)
                        continue;

                if (pmap_port_isfree (p)) {
                        pmap->ports[p].used = 1;
                        port = p;
                        break;
                }
        }

        return port;
}



int
pmap_registry_bind (xlator_t *this, int port, const char *brickname)
{
        struct pmap_registry *pmap = NULL;
        int                   p = 0;

        pmap = pmap_registry_get (this);

        pmap->ports[p].used = 1;
        if (pmap->ports[p].brickname)
                free (pmap->ports[p].brickname);
        pmap->ports[p].brickname = strdup (brickname);

        return 0;
}


typedef ssize_t (*gfs_serialize_t) (struct iovec outmsg, void *data);


static int
xdr_to_glusterfs_req (rpcsvc_request_t *req, void *arg, gfs_serialize_t sfunc)
{
        int                     ret = -1;

        if (!req)
                return -1;

        ret = sfunc (req->msg[0], arg);

        if (ret > 0)
                ret = 0;
{'fraction_non_alphanumeric': 0.10411086526144171, 'fraction_numerical': 0.013275882147432165, 'mean_word_length': 1.5945619335347432, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6190149', 'n_tokens_mistral': 2906, 'n_tokens_neox': 2674, 'n_words': 791}