735 lines
22 KiB
C
735 lines
22 KiB
C
/*
|
|
* 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
|
|
|
|
/*----------------------
|
|
* global variables
|
|
*----------------------*/
|
|
|
|
#define EMSGMAX 4096
|
|
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);
|
|
snprintf(g_errorMessage, sizeof(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 */
|
|
|
|
#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
|
|
* 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);
|
|
snprintf(g_errorMessage, sizeof(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, 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");
|
|
}
|
|
}
|
|
*/
|
|
|