Logo Search packages:      
Sourcecode: eiciel version File versions  Download package

gestor_xattr.cpp

/*
    Eiciel - GNOME editor of ACL file permissions.
    Copyright (C) 2004-2005 Roger Ferrer Ib߽ez

    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 2 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, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
#include "gestor_xattr.hpp"

GestorXAttr::GestorXAttr(const Glib::ustring& nomF) throw (GestorXAttrException)
      : nomFitxer(nomF)
{
      // Comprovem que es un fitxer normal o directori
      struct stat buffer;
      if (stat(nomFitxer.c_str(), &buffer) == -1)
      {
            throw GestorXAttrException(Glib::locale_to_utf8(strerror(errno)));
      }

      // Comprovem si es un fitxer regular o un directori
      if (!S_ISREG(buffer.st_mode) && !S_ISDIR(buffer.st_mode))
      {
            throw GestorXAttrException(_("Only regular files or directories supported")); // De moment...
      }

      this->propietari = buffer.st_uid;
      
      // Aixo es pq salti una excepcio si cal
      testLectura();
}

void GestorXAttr::testLectura() throw (GestorXAttrException)
{
      Glib::ustring nomAttrQualif = "user.prova";
      int longitudBuffer;
      int mida = 30;
      char* buffer = new char[mida];

      longitudBuffer = getxattr (nomFitxer.c_str(), nomAttrQualif.c_str(),
                  buffer, mida);

      if (longitudBuffer == -1 && 
                  errno != ENOATTR && 
                  errno != ERANGE)
      {
            delete[] buffer;
            throw GestorXAttrException(Glib::locale_to_utf8(strerror(errno)));
      }

      delete[] buffer;
}

std::vector<std::string> GestorXAttr::obtenirLlistaXAttr() throw (GestorXAttrException)
{
      std::vector<std::string> resultat;

    int mida = listxattr(nomFitxer.c_str(), NULL, 0);

      // Calculem que la longitud de cada element serÓ d'uns 30 carÓcters com a molt
      mida = mida*30;
      char* buffer = new char[mida];

      int numElements;
      numElements = listxattr(nomFitxer.c_str(), buffer, mida);

      while ((numElements == -1) && (errno == ERANGE))
      {
            delete[] buffer;
            mida = mida*2;
            buffer = new char[mida];
            numElements = listxattr(nomFitxer.c_str(), buffer, mida);
      }

      // numElements == -1 && errno != ERANGE
      if (numElements == -1)
      {
            delete[] buffer;
            throw GestorXAttrException(Glib::locale_to_utf8(strerror(errno)));
      }

      for (int inici = 0, actual = 0; actual < numElements; actual++)
      {
            if (buffer[actual] == '\0')
            {
                  // Ara recuperem cada valor
                  std::string nomAttr(&buffer[inici]);

            // Alguns FS retornen un nom d'atribut massa petit
            if (nomAttr.size() > 5)
            {
                std::string prefix =  nomAttr.substr(0, 5);
                std::string postfix = nomAttr.substr(5);

                if (prefix == "user.")
                {
                    // Comprovem que el FS retorna alguna cosa ...
                    bool esBuit = false;

                    try
                    {
                        std::string valorAtribut = recuperarValorAtribut(postfix);
                    }
                    catch (GestorXAttrException e)
                    {
                        esBuit = true;
                    }

                    if (!esBuit)
                    {
                        resultat.push_back(postfix);
                    }
                }
            }
                  
                  inici = actual + 1;
            }
      }
      
      delete[] buffer;

      return resultat;
}

std::string GestorXAttr::recuperarValorAtribut(const std::string& nomAttr) throw (GestorXAttrException)
{
      int mida = 30;
      char* buffer = new char[mida];

      std::string nomAttrQualif = "user." + nomAttr;

      int longitudBuffer = getxattr (nomFitxer.c_str(), nomAttrQualif.c_str(),
                  buffer, mida);

      while ((longitudBuffer == -1) && (errno == ERANGE))
      {
            delete[] buffer;
            mida = mida*2;
            buffer = new char[mida];

            longitudBuffer = getxattr (nomFitxer.c_str(), nomAttrQualif.c_str(),
                        buffer, mida);
      }

      if (longitudBuffer == -1)
      {
            delete[] buffer;
            throw GestorXAttrException(Glib::locale_to_utf8(strerror(errno)));
      }

      char* nouBuffer = new char[longitudBuffer + 1];
      nouBuffer[longitudBuffer] = '\0';

      for (int i = 0; i < longitudBuffer; i++)
      {
            nouBuffer[i] = buffer[i];
      }

      std::string valorAttr(nouBuffer);

      delete[] nouBuffer;
      delete[] buffer;

      return valorAttr;
}

GestorXAttr::atributs_t GestorXAttr::donarLlistaAtributs()
{
      std::vector<std::string> atributs;
      std::vector<std::string>::iterator it;

      atributs = obtenirLlistaXAttr();

      atributs_t resultat;

      for (it = atributs.begin(); it != atributs.end(); it++)
      {
            std::string valorAttr = recuperarValorAtribut(*it);

            resultat[*it] = valorAttr;
      }

      return resultat;
}

void GestorXAttr::eliminarAtribut(std::string nomAtr)
{
      std::string nomQualif = "user." + nomAtr;
      int result = removexattr (nomFitxer.c_str(), nomQualif.c_str());

      if (result != 0)
      {
            throw GestorXAttrException(Glib::locale_to_utf8(strerror(errno)));
      }
}

void GestorXAttr::afegirAtribut(std::string nomAtr, std::string valor)
{
      std::string nomQualif = "user." + nomAtr;
      int resultat = setxattr (nomFitxer.c_str(), nomQualif.c_str(),
                  valor.c_str(), strlen(valor.c_str()), 0);

      if (resultat != 0)
      {
            throw GestorXAttrException(Glib::locale_to_utf8(strerror(errno)));
      }
}

void GestorXAttr::canviarNomAtribut(std::string anticNomAttr, std::string nouNomAttr)
{
      std::string valorAtribut = recuperarValorAtribut(anticNomAttr);
      afegirAtribut(nouNomAttr, valorAtribut);
      eliminarAtribut(anticNomAttr);
}

Generated by  Doxygen 1.6.0   Back to index