123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they 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 these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* $XConsortium: fsDialog.c /main/6 1996/10/08 11:58:08 mustafa $ */
- /************************************<+>*************************************
- ****************************************************************************
- *
- * FILE: fsDialog.c
- *
- * COMPONENT_NAME: Desktop File Manager (dtfile)
- *
- * Description: Containes routines to handle contents of dtfile.config
- *
- * FUNCTIONS: configFileName
- * configFileOK
- * fsDialogAvailable
- * getFSType
- * readConfigFile
- * readDialogData
- * readFSID
- * readLine
- * stricmp
- * strip
- *
- * (c) Copyright 1993, 1994, 1995 Hewlett-Packard Company
- * (c) Copyright 1993, 1994, 1995 International Business Machines Corp.
- * (c) Copyright 1993, 1994, 1995 Sun Microsystems, Inc.
- * (c) Copyright 1993, 1994, 1995 Novell, Inc.
- *
- ****************************************************************************
- ************************************<+>*************************************/
- /*---------------------------------------------------------------------------------
- *
- * fsDialogAvailable (String path, dtFSData *fsDialogData)
- *
- * For the file specified by path, determine if there is a properties
- * dialog specific to the file system that the file is on.
- * For example, if the file is in AFS there might be a dialog to edit
- * the Access Control List. fsDialogData is filled if there is a dialog.
- * path must not include host:
- *
- * If any errors are encountered, FALSE is returned and no other action is taken
- * or message displayed.
- *
- *--------------------------------------------------------------------------------*/
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <errno.h>
- #include <sys/stat.h>
- #include <Dt/UserMsg.h> /* for DtSimpleError */
- #include <Xm/Xm.h>
- #include "Encaps.h"
- #include "ModAttr.h"
- #include "FileMgr.h"
- #include "Desktop.h"
- #include "Main.h"
- /*-----------------------------------------------------
- * Configuration file search order is:
- *
- * $DTFSCONFIG (meant to be used for debugging)
- * $HOME/CONFIGFILENAME
- * SYSCONFIGFILEDIR/CONFIGFILENAME
- * DEFCONFIGFILEDIR/$LANG/CONFIGFILENAME
- * DEFCONFIGFILEDIR/C/CONFIGFILENAME
- *
- * The function configFileName() determines the correct
- * name. It will apply $LANG where appropriate.
- *
- *-----------------------------------------------------*/
- #define SYSCONFIGFILEDIR CDE_CONFIGURATION_TOP "/config"
- #define DEFCONFIGFILEDIR CDE_INSTALLATION_TOP "/config"
- #define CONFIGFILENAME "dtfile.config"
- #define DEFCONFIGFILENAME CDE_INSTALLATION_TOP "/config/C/dtfile.config"
- /*--------------------------------------------------------
- Platform-specific includes required for getFSType()
- *--------------------------------------------------------*/
- #ifdef __aix
- #endif
- #if defined(sun)
- #include <sys/types.h>
- #include <sys/statvfs.h>
- #endif
- #ifdef __hpux
- #include <sys/vfs.h>
- #endif
- /*----------------------
- * global variables
- *----------------------*/
- #define EMSGMAX 1024
- char g_errorMessage[EMSGMAX];
- /*--------------------
- Local functions
- *--------------------*/
- static void getFSType (const String path,
- String fsType,
- String platform);
- static void readConfigFile (const String fsType,
- const String platform,
- dtFSData * fsDialogData,
- Boolean * dialogAvailable);
- static String configFileName (void);
- static void readFSID (FILE * fptr,
- const String fsType,
- const String platform,
- String fsID);
- static void readDialogData (FILE * fptr,
- const String fsID,
- Boolean * dialogAvailable,
- dtFSData * fsDialogData);
- static int readLine (FILE * fptr, String line);
- static int stricmp (const String s1, const String s2);
- static String strip (String s);
- static Boolean configFileOK(void);
- /*----------------------
- * fsDialogAvailable
- *----------------------*/
- Boolean
- fsDialogAvailable (const String path, dtFSData *fsDialogData)
- {
- char fsType[MAXLINELENGTH], platform[MAXLINELENGTH];
- Boolean dialogAvailable;
- DPRINTF(("fsDialogAvailble: checking path \"%s\"\n",path));
- if ( ! configFileOK())
- return FALSE;
- getFSType(path, fsType, platform);
- DPRINTF((" fsType=\"%s\"\n platform=\"%s\"\n",fsType,platform));
- if (strlen(fsType) == 0)
- return FALSE;
- else
- {
- readConfigFile(fsType, platform, fsDialogData, &dialogAvailable);
- if (dialogAvailable)
- {
- strcpy (fsDialogData->path,path);
- }
- return dialogAvailable;
- }
- }
- /*--------------------------------------------------------------------------------
- *
- * configFileOK
- *
- * is the configuration file accessible?
- *
- *------------------------------------------------------------------------------*/
- static Boolean
- configFileOK(void)
- {
- struct stat buf;
- int err;
- String fname;
- String msg1, msg2;
- fname = configFileName();
- err = stat(fname, &buf);
- DPRINTF((" config file \"%s\" stat ret=%i\n",fname,err));
- if (err == 0)
- return TRUE;
- else
- {
- msg1 = GETMESSAGE(21, 22, "Cannot open file manager configuration file: ");
- msg2 = strerror(errno);
- sprintf(g_errorMessage,"%s%s\n %s\n",msg1,fname,msg2);
- _DtSimpleError (application_name, DtError, NULL, g_errorMessage, NULL);
- return FALSE;
- }
- } /* end configFileOK */
- /*--------------------------------------------------------------------------------
- *
- * getFSType
- *
- * Do the platform-specific work required to determine what type of file system
- * the file defined by path is on. Return strings defining the file system type
- * and the platform. Any errors result in a fsType set to the null string.
- *
- * Both fsType and platform are allocated by the caller
- *
- * The strings used in platform and fsType must match those used in
- * the configuration file.
- *
- *--------------------------------------------------------------------------------*/
- static void getFSType(const String path,
- String fsType,
- String platform)
- {
- #ifdef __aix
- #define GETFSTYPE
- struct stat buf;
- strncpy(platform,"aix",MAXLINELENGTH);
- if (lstat(path, &buf) == 0)
- sprintf(fsType,"%i",buf.st_vfstype);
- else
- strncpy(fsType,"",MAXLINELENGTH);
- #endif /* __aix */
- #ifdef sun
- #define GETFSTYPE
- struct statvfs buf;
- strncpy(platform,"sunos",MAXLINELENGTH);
- if (statvfs(path, &buf) == 0)
- strncpy(fsType,buf.f_basetype,MAXLINELENGTH);
- else
- strncpy(fsType,"",MAXLINELENGTH);
- #endif /* sun */
- #ifdef __hpux
- #define GETFSTYPE
- struct statfs buf;
- strncpy(platform,"hpux",MAXLINELENGTH);
- if (statfs(path, &buf) == 0)
- sprintf(fsType,"%li",buf.f_fsid[1]);
- else
- strncpy(fsType,"",MAXLINELENGTH);
- #endif /* __hpux */
- #ifndef GETFSTYPE
- strncpy(platform,"unknown",MAXLINELENGTH);
- strncpy(fsType, "",MAXLINELENGTH);
- #endif /* unknown platform */
- return;
- } /* end getFSType */
- /*--------------------------------------------------------------------------------
- *
- * readConfigFile
- *
- * Given the platform and type of file system, read the configuration file to
- * determine if there is a file-system specific dialog. If there is, fill
- * fsDialogData. If there is no file or if the file has no entry for
- * platform:fsType, dialogAvailable is set to FALSE.
- *
- * The configuration file consists of two parts. The first is a list of entries
- * (ending with "end") of the form
- *
- * platform:file-system-type=file-system-id
- *
- * where platform is one of the strings from getFSType(), file-system-type is
- * a (platform-dependent) string identifying the type of file system, and
- * file-system-id is a string used in the configuration file to identify the
- * file system. The second part of the file consists of lists of attributes
- * (in the form name = value, one per line) for each of the file system id's.
- * Blank lines and lines beginning with * are ignored as is case. A example
- * is given below.
- *
- * -------------------------------------------------
- * * sample dtfs configuration file
- *
- * aix:4=afs
- * hpux:8=afs
- * sunos:nfs=nfs
- * end
- *
- * afs: buttonlabel = Change AFS ACL ...
- * fsDialog = modAttrAFS
- * warning = File system access may be further restriced by AFS ACLs
- *
- * nfs: buttonLabel = Change NFS attributes ...
- * fsDialog = <configuration-location>/bin/modNFSAttr
- * -------------------------------------------------
- *
- *--------------------------------------------------------------------------------*/
- static void
- readConfigFile(const String fsType,
- const String platform,
- dtFSData * fsDialogData,
- Boolean * dialogAvailable)
- {
- char fsID[MAXLINELENGTH];
- FILE * fptr;
- String fname, msg1, msg2;
- *dialogAvailable = FALSE;
- fname = configFileName();
- fptr = fopen(fname,"r");
- if (fptr == NULL)
- {
- msg1 = GETMESSAGE(21, 22, "Cannot open file manager configuration file: ");
- msg2 = strerror(errno);
- sprintf(g_errorMessage,"%s%s\n %s\n",msg1,fname,msg2);
- _DtSimpleError (application_name, DtError, NULL, g_errorMessage, NULL);
- return;
- }
- readFSID(fptr, fsType, platform, fsID);
- DPRINTF((" fsID=\"%s\"\n",fsID));
- readDialogData(fptr, fsID, dialogAvailable, fsDialogData);
- /* make sure that a dialog program has been specified or execl will do unfortunate things */
- if (strlen(fsDialogData->fsDialogProgram) == 0)
- {
- *dialogAvailable = FALSE;
- if (strlen(fsDialogData->buttonLabel) != 0)
- {
- msg1 = XtNewString(GETMESSAGE(21, 29, "No value was provided for the fsDialog field in dtfile's configuration file"));
- _DtSimpleError (application_name, DtError, NULL, msg1, NULL);
- XtFree(msg1);
- }
- }
- fclose(fptr);
- return;
- } /* end readConfigFile */
- /*--------------------------------------------------------------------------------
- *
- * configFileName
- *
- * return the name of the configuration file which defines file-system
- * specific dialogs ... a hierarchy of names is searched until a file
- * is found ... no checking is done to see if it can be read
- *
- *------------------------------------------------------------------------------*/
- static String
- configFileName(void)
- {
- int i, err;
- struct stat buf;
- String s;
- static char fn[MAX_PATH]=""; /* remember name once its been determined */
- if (strlen(fn) != 0) return fn; /* has filename been determined already? */
- for (i=0; i < 4; i++)
- {
- switch (i)
- {
- case 0: /* file name $DTFSCONFIG */
- if ( (s=getenv("DTFSCONFIG")) != NULL) /* a convenience for debugging */
- strncpy(fn,s,MAX_PATH);
- else /* DTFSCONFIG not defined */
- continue;
- break;
- case 1: /* $HOME/dtfile.config */
- if ( (s=getenv("HOME")) != NULL)
- {
- strncpy(fn,s,MAX_PATH);
- strcat (fn,"/");
- strncat(fn,CONFIGFILENAME,MAX_PATH-strlen(fn)-1);
- }
- else /* $HOME not defined */
- continue;
- break;
- case 2: /* SYSCONFIGFILEDIR, e.g. /etc/dt/config/dtfile.config */
- strncpy(fn,SYSCONFIGFILEDIR,MAX_PATH);
- strcat (fn,"/");
- strncat(fn,CONFIGFILENAME,MAX_PATH-strlen(fn)-1);
- break;
- case 3: /* DEFCONFIGFILEDIR, e.g. /usr/dt/config/C/dtfile.config */
- strncpy(fn,DEFCONFIGFILEDIR,MAX_PATH);
- strcat (fn,"/");
- if ( (s=getenv("LANG")) != NULL)
- {
- strncat(fn,s,MAX_PATH-strlen(fn)-1);
- strcat (fn,"/");
- }
- else
- {
- strncat(fn,"C",MAX_PATH-strlen(fn)-1);
- strcat (fn,"/");
- }
- strncat(fn,CONFIGFILENAME,MAX_PATH-strlen(fn)-1);
- break;
- } /* end switch */
- err = stat(fn, &buf);
- DPRINTF((" config file \"%s\" stat ret=%i\n",fn,err));
- if (err == 0) /* file is found */
- return fn;
- } /* end loop over possible config files */
- /* didn't find any of the files (this should never, ever happen) */
- /* return the name of the factory default (case 3 above) which should always be there */
- strncpy(fn,DEFCONFIGFILENAME,MAX_PATH);
- return fn;
- } /* end configFileName */
- /*--------------------------------------------------------------------------------
- *
- * readFSID
- *
- * get the file-system identifier from the configuration file
- *
- * fptr refers to an open configuration file
- * fsType and platform identify the platfrom (aix, hpux, sunos, etc)
- * and file-system type (afs, nfs, dfs, etc.)
- * fsID is filled by matching platform:fsType with with information in the
- * file and reading the id; the string comparisons are case insensitive
- * if there is more than one match, the last fsID found will be returned;
- * if no match is found, fsID is returned as ""
- * upon conclusion, the file is positioned past the "end" record
- *
- *------------------------------------------------------------------------------*/
- static void
- readFSID ( FILE * fptr,
- const String fsType,
- const String platform,
- String fsID)
- {
- char line[MAXLINELENGTH];
- String pform, type, id;
- int lineLength;
- String lineIn, lineOut;
- fsID[0] = '\0';
- while ( (lineLength=readLine(fptr,line)) != EOF &&
- stricmp(line,"end") != 0 )
- {
- /* readLine has changed all white space to blanks ... now remove
- the blanks as they are not significant here */
- for (lineIn = lineOut = line; *lineIn != '\0'; lineIn++)
- if (*lineIn != ' ')
- {
- *lineOut = *lineIn;
- lineOut++;
- }
- *lineOut = '\0';
- pform = strtok(line,":");
- type = strtok(NULL,"=");
- id = strtok(NULL," ");
- if (stricmp(pform,platform)==0 && stricmp(type,fsType)==0)
- strncpy(fsID,id,MAXLINELENGTH);
- }
- return;
- } /* end readFSID */
- /*--------------------------------------------------------------------------------
- *
- * readDialogData
- *
- * fill dtFSData with information from the configuration file; set
- * dialogAvailable
- *
- * fsID is a file-system identifier defined, in the configuration file,
- * by a platform:file-system-type pair. The configuration file is
- * searched from its current position until a definition section
- * for fsID is found. The string comparison is case insensitive; if more
- * than one match is found, the last in the file is used. The fields in
- * dtFSData are initialized (e.g. string fields are set to "") if no
- * matches are found or if no match is found for a particular field.
- * Upon conclusion, the file is positioned at EOF.
- *
- *------------------------------------------------------------------------------*/
- static void
- readDialogData( FILE * fptr,
- const String fsID,
- Boolean * dialogAvailable,
- dtFSData * fsDialogData)
- {
- int lineLength;
- String s, id, token1, token2;
- String msg1;
- char line[MAXLINELENGTH];
- *dialogAvailable = FALSE;
- /* initialize fields in fsDialogData */
- strcpy(fsDialogData->buttonLabel,"");
- strcpy(fsDialogData->fsDialogProgram,"");
- strcpy(fsDialogData->warningMessage,"");
- fsDialogData->dismissStdPermissionDialog = FALSE;
- if (strlen(fsID) == 0)
- return;
- /* loop over lines in the file; note that readLine is called
- from within the loop except for the first pass */
- for (lineLength=readLine(fptr,line); lineLength != EOF; )
- {
- id = strtok(line,":");
- if (stricmp(id,fsID) == 0)
- {
- /* a section matching the input fsID has been found */
- *dialogAvailable = TRUE;
- token1 = strtok(NULL," =");
- s = strchr(token1,'\0') + 1; /* first character after token1 */
- token2 = &s[strspn(s," =")]; /* first non-blank, non-= after token1 */
- /* loop to get data for fields in fsDialogData */
- while(strchr(token1,':') == NULL && lineLength != EOF)
- {
- if (stricmp(token1,"buttonlabel") == 0)
- strncpy(fsDialogData->buttonLabel,token2,MAXLINELENGTH);
- else if (stricmp(token1,"warning") == 0)
- {
- strncpy(fsDialogData->warningMessage,token2,MAXLINELENGTH);
- }
- else if (stricmp(token1,"fsdialog") == 0)
- strncpy(fsDialogData->fsDialogProgram,token2,MAXLINELENGTH);
- else if (stricmp(token1,"dismiss") == 0)
- fsDialogData->dismissStdPermissionDialog = (stricmp(token2,"yes") == 0);
- else
- {
- msg1 = GETMESSAGE(21, 24, "Unknown field label in file manager configuration file: ");
- sprintf(g_errorMessage,"%s\"%s\"\n",msg1,token1);
- _DtSimpleError (application_name, DtWarning, NULL, g_errorMessage, NULL);
- }
- lineLength = readLine(fptr,line);
- if (lineLength != EOF)
- {
- token1 = strtok(line," =");
- s = strchr(token1,'\0') + 1;
- token2 = &s[strspn(s," =")];
- }
- } /* end while */
- } /* end if */
- else
- {
- /* the current line does not match fsID ... get next line */
- lineLength = readLine(fptr,line);
- }
- } /* end for */
- if ( ! *dialogAvailable )
- {
- msg1 = GETMESSAGE(21, 25, "No information found in file manager configuration file for file-system identifier");
- sprintf(g_errorMessage,"%s \"%s\"\n",msg1,fsID);
- _DtSimpleError (application_name, DtError, NULL, g_errorMessage, NULL);
- }
- } /* end readDialogData */
- /*--------------------------------------------------------------------------------
- *
- * readLine
- *
- * read a line from the stream pointed to by fptr and return it in line
- * line is allocated by the caller
- *
- * blank lines and lines starting with * are skipped
- * leading and trailing white space is removed
- * imbedded white space characters are changed to blanks
- * imbedded "\n" is changed to space, newline
- * the length of the line or EOF (on end-of-file or error) is returned
- *
- *------------------------------------------------------------------------------*/
- static int
- readLine(FILE * fptr, String line)
- {
- const char commentChar = '#';
- char myLine[MAXLINELENGTH];
- String s, t;
- int i, len;
- while (TRUE)
- {
- if ( fgets(myLine,MAXLINELENGTH,fptr) == NULL)
- return EOF;
- else
- {
- s = strip(myLine); /* remove leading & trailing whitespace */
- if ((len=strlen(s)) != 0 && s[0] != commentChar)
- {
- /* change imbedded white space characters to spaces */
- for (i=0; i<len; i++)
- if (isspace(s[i]))
- s[i] = ' ';
- /* change any imbedded "\n" to space followed by newline */
- while ( (t=strstr(s,"\\n")) != NULL )
- {
- *t = ' '; /* space */
- *(t+1) = '\n'; /* new line */
- }
- strncpy(line,s,MAXLINELENGTH);
- return len;
- }
- }
- }
- } /* end readLine */
- /*--------------------------------------------------------------------------------
- *
- * stricmp
- *
- * compare strings ignoring case, return value as in strcmp
- *
- *------------------------------------------------------------------------------*/
- static int
- stricmp(const String s1, const String s2)
- {
- int i;
- for (i=0; tolower(s1[i]) == tolower(s2[i]); i++)
- if (s1[i] == '\0')
- return 0;
- return (tolower(s1[i]) > tolower(s2[i])) ? +1 : -1;
- } /* end stricmp */
- /*--------------------------------------------------------------------------------
- *
- * strip
- *
- * remove trailing white space by inserting \0
- * return a pointer to the first non-white space character
- *------------------------------------------------------------------------------*/
- static String
- strip(String s)
- {
- int i;
- for (i=(strlen(s)-1); isspace(s[i]) && i>=0; i--)
- ;
- s[i+1] = '\0';
- for (i=0; isspace(s[i]); i++)
- ;
- return &s[i];
- } /* end strip */
- /*----------------
- * for testing
- *----------------*/
- /*
- main(int argc, char **argv)
- {
- char pwd[100];
- int err = 0;
- Boolean test;
- dtFSData data;
- if(argc > 1)
- {
- strcpy(pwd, argv[1]);
- }
- else
- {
- getcwd(pwd,sizeof(pwd));
- }
- printf("testing file \"%s\"\n",pwd);
- test = fsDialogAvailable(pwd, &data);
- if (test)
- {
- printf("dialog is available\n");
- printf(" buttonLabel=\"%s\"\n",data.buttonLabel);
- printf(" fsDialogProgram=\"%s\"\n",data.fsDialogProgram);
- }
- else
- {
- printf("dialog not available\n");
- }
- }
- */
|