/* * Copyright (C) 2012 Red Hat, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Authors: Jan Synacek */ #include #include "LMI_DirectoryContainsFile.h" #include "LMI_UnixDirectory.h" #include "CIM_LogicalFile.h" #include "CIM_Directory.h" #include "file.h" static const CMPIBroker* _cb; /* XXX if a directory contains more than MAX_REFS files, * broker will abort with an error */ /* const unsigned int MAX_REFS = 65536; */ const unsigned int MAX_REFS = 4096; static CMPIStatus dir_file_objectpaths( const CMPIContext* cc, const CMPIResult* cr, const char** properties, const char *namespace, const char *path, CMPIObjectPath **ops, unsigned int *count) { CMPIObjectPath *o; CMPIStatus st; unsigned int i = 0; struct stat sb; struct dirent *de; DIR *dp; dp = opendir(path); while ((de = readdir(dp))) { if (!strcmp(de->d_name, ".")) { continue; } char rpath[BUFLEN]; char fileclass[BUFLEN]; char *aux = strdup(path); if (!strcmp(de->d_name, "..")) { strncpy(rpath, dirname(aux), BUFLEN); free(aux); } else { snprintf(rpath, BUFLEN, "%s/%s", (!strcmp(path, "/")) ? "" : path, de->d_name); } if (lstat(rpath, &sb) < 0) { char err[BUFLEN]; snprintf(err, BUFLEN, "Can't stat file: %s", rpath); CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, err); } else { (S_ISREG(sb.st_mode)) ? strcpy(fileclass, "LMI_DataFile") : (S_ISDIR(sb.st_mode)) ? strcpy(fileclass, "LMI_UnixDirectory") : (S_ISCHR(sb.st_mode)) ? strcpy(fileclass, "LMI_UnixDeviceFile") : (S_ISBLK(sb.st_mode)) ? strcpy(fileclass, "LMI_UnixDeviceFile") : (S_ISLNK(sb.st_mode)) ? strcpy(fileclass, "LMI_SymbolicLink") : (S_ISFIFO(sb.st_mode)) ? strcpy(fileclass, "LMI_FIFOPipeFile") : strcpy(fileclass, "Unknown"); } CIM_LogicalFileRef cim_lfr; CIM_LogicalFileRef_Init(&cim_lfr, _cb, namespace); fill_logicalfile(CIM_LogicalFileRef, &cim_lfr, rpath, fileclass); o = CIM_LogicalFileRef_ToObjectPath(&cim_lfr, &st); CMSetClassName(o, fileclass); ops[i++] = o; } *count = i; CMReturn(CMPI_RC_OK); } static CMPIStatus associators( CMPIAssociationMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* assocClass, const char* resultClass, const char* role, const char* resultRole, const char** properties, int names) { CMPIObjectPath *o; CMPIInstance *ci; CMPIStatus st; CMPIData cd, pathd; const char *ns = KNameSpace(cop); st = lmi_check_required(_cb, cop, LOGICALFILE); if (st.rc != CMPI_RC_OK) { return st; } cd = CMGetKey(cop, "CreationClassName", &st); const char *ccname = KChars(cd.value.string); pathd = CMGetKey(cop, "Name", &st); const char *path = KChars(pathd.value.string); CMPIObjectPath *refs[MAX_REFS]; unsigned int count; if (CMClassPathIsA(_cb, cop, LMI_UnixDirectory_ClassName, &st)) { /* UnixDirectory */ st = dir_file_objectpaths(cc, cr, properties, ns, path, refs, &count); if (st.rc != CMPI_RC_OK) { return st; } if (count > MAX_REFS) { CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Too many files in a single directory..."); } for (unsigned int i = 0; i < count; i++) { if (names) { CMReturnObjectPath(cr, refs[i]); } else { ci = _cb->bft->getInstance(_cb, cc, refs[i], properties, &st); CMReturnInstance(cr, ci); } } } else { /* LogicalFile */ CIM_LogicalFileRef cim_lfr; CIM_LogicalFileRef_Init(&cim_lfr, _cb, ns); fill_logicalfile(CIM_LogicalFileRef, &cim_lfr, path, ccname); o = CIM_LogicalFileRef_ToObjectPath(&cim_lfr, &st); CMSetClassName(o, ccname); if (names) { CMReturnObjectPath(cr, o); } else { ci = _cb->bft->getInstance(_cb, cc, o, properties, &st); CMReturnInstance(cr, ci); } } CMReturn(CMPI_RC_OK); } static CMPIStatus references( CMPIAssociationMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* assocClass, const char* role, const char** properties, int names) { LMI_DirectoryContainsFile lmi_dcf; CMPIStatus st; CMPIData pathd; CMPIData cd; const char *ns = KNameSpace(cop); /* GroupComponent */ CIM_DirectoryRef lmi_dr; /* PartComponent */ CIM_LogicalFileRef lmi_lfr; CMPIObjectPath *o; CMPIInstance *ci; CIM_DirectoryRef_Init(&lmi_dr, _cb, ns); CIM_LogicalFileRef_Init(&lmi_lfr, _cb, ns); LMI_DirectoryContainsFile_Init(&lmi_dcf, _cb, ns); st = lmi_check_required(_cb, cop, LOGICALFILE); if (st.rc != CMPI_RC_OK) { return st; } cd = CMGetKey(cop, "CreationClassName", &st); const char *ccname = KChars(cd.value.string); pathd = CMGetKey(cop, "Name", &st); const char *path = KChars(pathd.value.string); if (!strcmp(ccname, LMI_UnixDirectory_ClassName)) { /* got GroupComponent - DirectoryRef */ fill_logicalfile(CIM_DirectoryRef, &lmi_dr, path, LMI_UnixDirectory_ClassName); o = CIM_DirectoryRef_ToObjectPath(&lmi_dr, &st); CMSetClassName(o, LMI_UnixDirectory_ClassName); LMI_DirectoryContainsFile_SetObjectPath_GroupComponent(&lmi_dcf, o); /* PartComponent */ CMPIObjectPath *refs[MAX_REFS]; unsigned int count; st = dir_file_objectpaths(cc, cr, properties, ns, path, refs, &count); if (st.rc != CMPI_RC_OK) { return st; } if (count > MAX_REFS) { CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Too many files in a single directory..."); } for (unsigned int i = 0; i < count; i++) { if (names) { LMI_DirectoryContainsFile_SetObjectPath_PartComponent(&lmi_dcf, refs[i]); o = LMI_DirectoryContainsFile_ToObjectPath(&lmi_dcf, &st); CMReturnObjectPath(cr, o); } else { ci = _cb->bft->getInstance(_cb, cc, refs[i], properties, &st); CMReturnInstance(cr, ci); } } } else { /* got PartComponent - LogicalFileRef */ fill_logicalfile(CIM_LogicalFileRef, &lmi_lfr, path, ccname); o = CIM_LogicalFileRef_ToObjectPath(&lmi_lfr, &st); CMSetClassName(o, ccname); LMI_DirectoryContainsFile_SetObjectPath_PartComponent(&lmi_dcf, o); /* GroupComponent */ char *aux = strdup(path); fill_logicalfile(CIM_DirectoryRef, &lmi_dr, dirname(aux), LMI_UnixDirectory_ClassName); o = CIM_DirectoryRef_ToObjectPath(&lmi_dr, &st); CMSetClassName(o, LMI_UnixDirectory_ClassName); if (names) { LMI_DirectoryContainsFile_SetObjectPath_GroupComponent(&lmi_dcf, o); o = LMI_DirectoryContainsFile_ToObjectPath(&lmi_dcf, &st); CMReturnObjectPath(cr, o); } else { ci = _cb->bft->getInstance(_cb, cc, o, properties, &st); CMReturnInstance(cr, ci); } free(aux); } CMReturn(CMPI_RC_OK); } static void LMI_DirectoryContainsFileInitialize() { } static CMPIStatus LMI_DirectoryContainsFileCleanup( CMPIInstanceMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_DirectoryContainsFileEnumInstanceNames( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_DirectoryContainsFileEnumInstances( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char** properties) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_DirectoryContainsFileGetInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char** properties) { /* TODO TBI */ CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_DirectoryContainsFileCreateInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_DirectoryContainsFileModifyInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const CMPIInstance* ci, const char**properties) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_DirectoryContainsFileDeleteInstance( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_DirectoryContainsFileExecQuery( CMPIInstanceMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* lang, const char* query) { CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_DirectoryContainsFileAssociationCleanup( CMPIAssociationMI* mi, const CMPIContext* cc, CMPIBoolean term) { CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_DirectoryContainsFileAssociators( CMPIAssociationMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* assocClass, const char* resultClass, const char* role, const char* resultRole, const char** properties) { return associators(mi, cc, cr, cop, assocClass, resultClass, role, resultRole, properties, 0); } static CMPIStatus LMI_DirectoryContainsFileAssociatorNames( CMPIAssociationMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* assocClass, const char* resultClass, const char* role, const char* resultRole) { return associators(mi, cc, cr, cop, assocClass, resultClass, role, resultRole, NULL, 1); } static CMPIStatus LMI_DirectoryContainsFileReferences( CMPIAssociationMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* assocClass, const char* role, const char** properties) { return references(mi, cc, cr, cop, assocClass, role, properties, 0); } static CMPIStatus LMI_DirectoryContainsFileReferenceNames( CMPIAssociationMI* mi, const CMPIContext* cc, const CMPIResult* cr, const CMPIObjectPath* cop, const char* assocClass, const char* role) { return references(mi, cc, cr, cop, assocClass, role, NULL, 1); } CMInstanceMIStub( LMI_DirectoryContainsFile, LMI_DirectoryContainsFile, _cb, LMI_DirectoryContainsFileInitialize()) CMAssociationMIStub( LMI_DirectoryContainsFile, LMI_DirectoryContainsFile, _cb, LMI_DirectoryContainsFileInitialize()) KONKRET_REGISTRATION( "root/cimv2", "LMI_DirectoryContainsFile", "LMI_DirectoryContainsFile", "instance association") /* vi: set et: */