I expected you will not have a problem that I have not gotten back to you, 
since
it took you 6 mos to get back to me, and now I have to dig through archives 
to find the source code.

The code is attached.
filepro_is_deleted is the new function

At 12:23 PM 2/20/01 +0000, you wrote:
>ID: 5440
>Updated by: sniper
>Reported By: [EMAIL PROTECTED]
>Old-Status: Feedback
>Status: Closed
>Old-Bug Type: filePro related
>Bug Type: Feature/Change Request
>Assigned To:
>Comments:
>
>No feedback. Changed to change request. Reopen if still a problem for you.
>
>--Jani
>
>
>Previous Comments:
>---------------------------------------------------------------------------
>
>[2001-01-18 09:40:47] [EMAIL PROTECTED]
>If you have made some improvements for the code,
>please send a patch made against the latest CVS
>(cvs diff -u)
>and someone will commit it if it is good.
>
>--Jani
>
>---------------------------------------------------------------------------
>
>[2000-07-07 20:32:08] [EMAIL PROTECTED]
>filepro access has some major design flaws.
>
>The two functions that are currently used to pull data from a db are 
>filepro_rowcount, and filepro_retrieve.  filepro_rowcount returns the 
>number of rows in the db that are NOT deleted.  filepro_retrieve returns a 
>row/column of the database, regardless of whether or not the row is (not) 
>deleted.  This makes it impossible for php to actually retrieve only the 
>undeleted rows from the table.
>
>Recommendations:
>We have added an additional function in order to check if a row is deleted 
>(filepro_is_deleted), and are happy to contribute this code.  However, 
>because of the inefficiency of the current retrieve function, we recommend 
>adding a new function to obsolete the retrieve function.   This function 
>should be written like the dbase getrecord function, that returns a 
>deleted member along with all the fields in a given record.
>
>In addition, the filepro_rowcount function is essentially useless, since 
>it gives you the number of undeleted records.  In order to improve the 
>results of someone who is currently using this to iterate through their 
>db, it is recommended that this function be changed to return the total 
>(deleted or undeleted) number of records.
>
>---------------------------------------------------------------------------
>
>
>
>ATTENTION! Do NOT reply to this email!
>To reply, use the web interface found at http://bugs.php.net/?id=5440&edit=2


/*
    +----------------------------------------------------------------------+
    | PHP version 4.0                                                      |
    +----------------------------------------------------------------------+
    | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group                   |
    +----------------------------------------------------------------------+
    | This source file is subject to version 2.02 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |
    | available at through the world-wide-web at                           |
    | http://www.php.net/license/2_02.txt.                                 |
    | If you did not receive a copy of the PHP license and are unable to   |
    | obtain it through the world-wide-web, please send a note to          |
    | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
    | Authors: Chad Robinson <[EMAIL PROTECTED]>                           |
    +----------------------------------------------------------------------+

   filePro 4.x support developed by Chad Robinson, [EMAIL PROTECTED]
   Contact Chad Robinson at BRT Technical Services Corp. for details.
   filePro is a registered trademark by Fiserv, Inc.  This file contains
   no code or information that is not freely available from the filePro
   web site at http://www.fileproplus.com/

  */

#include "php.h"
#include "safe_mode.h"
#include "fopen-wrappers.h"
#include <string.h>
#ifdef PHP_WIN32
#include <windows.h>
#else
#include <sys/param.h>
#endif
#include <errno.h>
#include "php_globals.h"

#include "php_filepro.h"
#if HAVE_FILEPRO

typedef struct fp_field {
         char *name;
         char *format;
         int width;
         struct fp_field *next;
} FP_FIELD;

#ifdef THREAD_SAFE
DWORD FPTls;
static int numthreads=0;

typedef struct fp_global_struct{
         char *fp_database;
         signed int fp_fcount;
         signed int fp_keysize;
         FP_FIELD *fp_fieldlist;
}fp_global_struct;

#define FP_GLOBAL(a) fp_globals->a

#define FP_TLS_VARS \
         fp_global_struct *fp_globals; \
         fp_globals=TlsGetValue(FPTls);

#else
#define FP_GLOBAL(a) a
#define FP_TLS_VARS
static char *fp_database = NULL;                        /* Database 
directory */
static signed int fp_fcount = -1;                       /* Column count */
static signed int fp_keysize = -1;                      /* Size of key 
records */
static FP_FIELD *fp_fieldlist = NULL;           /* List of fields */
#endif


PHP_MINIT_FUNCTION(filepro)
{
#ifdef THREAD_SAFE
         fp_global_struct *fp_globals;
#if defined(COMPILE_DL) || defined(COMPILE_DL_FILEPRO)
         CREATE_MUTEX(fp_mutex,"FP_TLS");
         SET_MUTEX(fp_mutex);
         numthreads++;
         if (numthreads==1){
         if ((FPTls=TlsAlloc())==0xFFFFFFFF){
                 FREE_MUTEX(fp_mutex);
                 return 0;
         }}
         FREE_MUTEX(fp_mutex);
#endif
         fp_globals = (fp_global_struct *) LocalAlloc(LPTR, 
sizeof(fp_global_struct));
         TlsSetValue(FPTls, (void *) fp_globals);
#endif
         FP_GLOBAL(fp_database)=NULL;
         FP_GLOBAL(fp_fcount)=-1;
         FP_GLOBAL(fp_keysize)=-1;
         FP_GLOBAL(fp_fieldlist)=NULL;

         return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(filepro)
{
#ifdef THREAD_SAFE
         fp_global_struct *fp_globals;
         fp_globals = TlsGetValue(FPTls);
         if (fp_globals != 0)
                 LocalFree((HLOCAL) fp_globals);
#if defined(COMPILE_DL) || defined(COMPILE_DL_FILEPRO)
         SET_MUTEX(fp_mutex);
         numthreads--;
         if (!numthreads){
         if (!TlsFree(FPTls)){
                 FREE_MUTEX(fp_mutex);
                 return 0;
         }}
         FREE_MUTEX(fp_mutex);
#endif
#endif
         return SUCCESS;
}


function_entry filepro_functions[] = {
         PHP_FE(filepro, 
NULL)
         PHP_FE(filepro_rowcount, 
NULL)
         PHP_FE(filepro_fieldname, 
NULL)
         PHP_FE(filepro_fieldtype, 
NULL)
         PHP_FE(filepro_fieldwidth, 
NULL)
         PHP_FE(filepro_fieldcount, 
NULL)
         PHP_FE(filepro_retrieve, 
NULL)
         PHP_FE(filepro_is_deleted, 
NULL)
         {NULL, NULL, NULL}
};

zend_module_entry filepro_module_entry = {
         "filepro", filepro_functions, PHP_MINIT(filepro), 
PHP_MSHUTDOWN(filepro), NULL, NULL, NULL, STANDARD_MODULE_PROPERTIES
};


#if defined(COMPILE_DL) || defined(COMPILE_DL_FILEPRO)
#include "dl/phpdl.h"
ZEND_GET_MODULE(filepro)
#if (WIN32|WINNT) && defined(THREAD_SAFE)

/*NOTE: You should have an odbc.def file where you
export DllMain*/
BOOL WINAPI DllMain(HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved)
{
     switch( ul_reason_for_call ) {
     case DLL_PROCESS_ATTACH:
                 if ((FPTls=TlsAlloc())==0xFFFFFFFF){
                         return 0;
                 }
                 break;
     case DLL_THREAD_ATTACH:
                 break;
     case DLL_THREAD_DETACH:
                 break;
         case DLL_PROCESS_DETACH:
                 if (!TlsFree(FPTls)){
                         return 0;
                 }
                 break;
     }
     return 1;
}
#endif
#endif

/*
  * LONG filePro(STRING directory)
  *
  * Read and verify the map file.  We store the field count and field info
  * internally, which means we become unstable if you modify the table while
  * a user is using it!  We cannot lock anything since Web connections don't
  * provide the ability to later unlock what we locked.  Be smart, be safe.
  */
PHP_FUNCTION(filepro)
{
         pval *dir;
         FILE *fp;
         char workbuf[256]; /* FIX - should really be the max filename 
length */
         char readbuf[256];
         char *strtok_buf = NULL;
         int i;
         FP_FIELD *new_field, *tmp;
         PLS_FETCH();
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &dir) == FAILURE) {
                 WRONG_PARAM_COUNT;
         }

         convert_to_string(dir);

         /* FIX - we should really check and free these if they are used! */
         FP_GLOBAL(fp_database) = NULL;
     FP_GLOBAL(fp_fieldlist) = NULL;
         FP_GLOBAL(fp_fcount) = -1;
     FP_GLOBAL(fp_keysize) = -1;

         sprintf(workbuf, "%s/map", dir->value.str.val);

         if (PG(safe_mode) && (!php_checkuid(workbuf, 2))) {
                 RETURN_FALSE;
         }

         if (php_check_open_basedir(workbuf)) {
                 RETURN_FALSE;
         }

         if (!(fp = V_FOPEN(workbuf, "r"))) {
                 php_error(E_WARNING, "filePro: cannot open map: [%d] %s",
                                         errno, strerror(errno));
                 RETURN_FALSE;
         }
         if (!fgets(readbuf, 250, fp)) {
                 fclose(fp);
                 php_error(E_WARNING, "filePro: cannot read map: [%d] %s",
                                         errno, strerror(errno));
                 RETURN_FALSE;
         }

         /* Get the field count, assume the file is readable! */
         if (strcmp(php_strtok_r(readbuf, ":", &strtok_buf), "map")) {
                 php_error(E_WARNING, "filePro: map file corrupt or 
encrypted");
                 RETURN_FALSE;
         }
         FP_GLOBAL(fp_keysize) = atoi(php_strtok_r(NULL, ":", &strtok_buf));
         php_strtok_r(NULL, ":", &strtok_buf);
         FP_GLOBAL(fp_fcount) = atoi(php_strtok_r(NULL, ":", &strtok_buf));

     /* Read in the fields themselves */
         for (i = 0; i < FP_GLOBAL(fp_fcount); i++) {
                 if (!fgets(readbuf, 250, fp)) {
                         fclose(fp);
                         php_error(E_WARNING, "filePro: cannot read map: 
[%d] %s",
                                                 errno, strerror(errno));
                         RETURN_FALSE;
                 }
                 new_field = emalloc(sizeof(FP_FIELD));
                 new_field->next = NULL;
                 new_field->name = estrdup(php_strtok_r(readbuf, ":", 
&strtok_buf));
                 new_field->width = atoi(php_strtok_r(NULL, ":", &strtok_buf));
                 new_field->format = estrdup(php_strtok_r(NULL, ":", 
&strtok_buf));

                 /* Store in forward-order to save time later */
                 if (!FP_GLOBAL(fp_fieldlist)) {
                         FP_GLOBAL(fp_fieldlist) = new_field;
                 } else {
                         for (tmp = FP_GLOBAL(fp_fieldlist); tmp; tmp = 
tmp->next) {
                                 if (!tmp->next) {
                                         tmp->next = new_field;
                                         tmp = new_field;
                                 }
                         }
                 }
         }
         fclose(fp);

         FP_GLOBAL(fp_database) = 
estrndup(dir->value.str.val,dir->value.str.len);

         RETVAL_TRUE;
}


/*
  * LONG filePro_rowcount(void)
  *
  * Count the used rows in the database.  filePro just marks deleted records
  * as deleted; they are not removed.  Since no counts are maintained we need
  * to go in and count records ourselves.  <sigh>
  *
  * Errors return false, success returns the row count.
  */
PHP_FUNCTION(filepro_rowcount)
{
         FILE *fp;
         char workbuf[MAXPATHLEN];
         char readbuf[256];
         int recsize = 0, records = 0;
         PLS_FETCH();
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 0) {
                 WRONG_PARAM_COUNT;
         }

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_FALSE;
         }

         recsize = FP_GLOBAL(fp_keysize) + 19; /* 20 bytes system info -1 
to save time later */

         /* Now read the records in, moving forward recsize-1 bytes each 
time */
         sprintf(workbuf, "%s/key", FP_GLOBAL(fp_database));

         if (PG(safe_mode) && (!php_checkuid(workbuf, 2))) {
                 RETURN_FALSE;
         }

         if (php_check_open_basedir(workbuf)) {
                 RETURN_FALSE;
         }

         if (!(fp = V_FOPEN(workbuf, "r"))) {
                 php_error(E_WARNING, "filePro: cannot open key: [%d] %s",
                                         errno, strerror(errno));
                 RETURN_FALSE;
         }
         while (!feof(fp)) {
                 if (fread(readbuf, 1, 1, fp) == 1) {
                         if (readbuf[0])
                                 records++;
                         fseek(fp, recsize, SEEK_CUR);
                 }
         }
     fclose(fp);

         RETVAL_LONG(records);
}


/*
  * STRING filePro_fieldname(LONG field_number)
  *
  * Errors return false, success returns the name of the field.
  */
PHP_FUNCTION(filepro_fieldname)
{
         pval *fno;
         FP_FIELD *lp;
         int i;
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &fno) == FAILURE) {
                 WRONG_PARAM_COUNT;
         }

         convert_to_long(fno);

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_FALSE;
         }

         for (i = 0, lp = FP_GLOBAL(fp_fieldlist); lp; lp = lp->next, i++) {
                 if (i == fno->value.lval) {
                         RETURN_STRING(lp->name,1);
                 }
         }

         php_error(E_WARNING,
                                 "filePro: unable to locate field number 
%d.\n",
                                 fno->value.lval);

         RETVAL_FALSE;
}


/*
  * STRING filePro_fieldtype(LONG field_number)
  *
  * Errors return false, success returns the type (edit) of the field
  */
PHP_FUNCTION(filepro_fieldtype)
{
         pval *fno;
         FP_FIELD *lp;
         int i;
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &fno) == FAILURE) {
                 WRONG_PARAM_COUNT;
         }

         convert_to_long(fno);

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_FALSE;
         }

         for (i = 0, lp = FP_GLOBAL(fp_fieldlist); lp; lp = lp->next, i++) {
                 if (i == fno->value.lval) {
                         RETURN_STRING(lp->format,1);
                 }
         }
         php_error(E_WARNING,
                                 "filePro: unable to locate field number 
%d.\n",
                                 fno->value.lval);
         RETVAL_FALSE;
}


/*
  * STRING filePro_fieldwidth(int field_number)
  *
  * Errors return false, success returns the character width of the field.
  */
PHP_FUNCTION(filepro_fieldwidth)
{
         pval *fno;
         FP_FIELD *lp;
         int i;
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &fno) == FAILURE) {
                 WRONG_PARAM_COUNT;
         }

         convert_to_long(fno);

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_FALSE;
         }

         for (i = 0, lp = FP_GLOBAL(fp_fieldlist); lp; lp = lp->next, i++) {
                 if (i == fno->value.lval) {
                         RETURN_LONG(lp->width);
                 }
         }
         php_error(E_WARNING,
                                 "filePro: unable to locate field number 
%d.\n",
                                 fno->value.lval);
         RETVAL_FALSE;
}


/*
  * LONG filePro_fieldcount(void)
  *
  * Errors return false, success returns the field count.
  */
PHP_FUNCTION(filepro_fieldcount)
{
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 0) {
                 WRONG_PARAM_COUNT;
         }

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_FALSE;
         }

         /* Read in the first line from the map file */
         RETVAL_LONG(FP_GLOBAL(fp_fcount));
}


/*
  * STRING filePro_retrieve(int row_number, int field_number)
  *
  * Errors return false, success returns the datum.
  */
PHP_FUNCTION(filepro_retrieve)
{
         pval *rno, *fno;
     FP_FIELD *lp;
     FILE *fp;
     char workbuf[MAXPATHLEN];
         char readbuf[1024]; /* FIX - Work out better buffering! */
     int i, fnum, rnum;
     long offset;
         PLS_FETCH();
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &rno, &fno) == 
FAILURE) {
                 WRONG_PARAM_COUNT;
         }

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_FALSE;
         }

         convert_to_long(rno);
         convert_to_long(fno);

         fnum = fno->value.lval;
         rnum = rno->value.lval;

     if (rnum < 0 || fnum < 0 || fnum >= FP_GLOBAL(fp_fcount)) {
         php_error(E_WARNING, "filepro: parameters out of range");
                 RETURN_FALSE;
     }

     offset = (rnum + 1) * (FP_GLOBAL(fp_keysize) + 20) + 20; /* Record 
location */
     for (i = 0, lp = FP_GLOBAL(fp_fieldlist); lp && i < fnum; lp = 
lp->next, i++) {
         offset += lp->width;
     }
     if (!lp) {
         php_error(E_WARNING, "filePro: cannot locate field");
                 RETURN_FALSE;
     }

         /* Now read the record in */
         sprintf(workbuf, "%s/key", FP_GLOBAL(fp_database));

         if (PG(safe_mode) && (!php_checkuid(workbuf, 2))) {
                 RETURN_FALSE;
         }

         if (php_check_open_basedir(workbuf)) {
                 RETURN_FALSE;
         }

         if (!(fp = V_FOPEN(workbuf, "r"))) {
                 php_error(E_WARNING, "filePro: cannot open key: [%d] %s",
                                         errno, strerror(errno));
             fclose(fp);
                 RETURN_FALSE;
         }
     fseek(fp, offset, SEEK_SET);
         if (fread(readbuf, lp->width, 1, fp) != 1) {
         php_error(E_WARNING, "filePro: cannot read data: [%d] %s",
                                         errno, strerror(errno));
             fclose(fp);
                 RETURN_FALSE;
     }
     readbuf[lp->width] = '\0';
     fclose(fp);
         RETURN_STRING(readbuf,1);
}

/*
  * LONG filePro_is_deleted(int row_number)
  *
  * return 1 if deleted (or invalid), 0 if not deleted
  */
PHP_FUNCTION(filepro_is_deleted)
{
         pval *rno;
     FP_FIELD *lp;
     FILE *fp;
     char workbuf[MAXPATHLEN];
         char readbuf[1024]; /* FIX - Work out better buffering! */
     int i, rnum;
     long offset;
         PLS_FETCH();
         FP_TLS_VARS;

         if (ARG_COUNT(ht) != 1 || getParameters(ht, 1, &rno) == FAILURE) {
                 WRONG_PARAM_COUNT;
         }

         if (!FP_GLOBAL(fp_database)) {
                 php_error(E_WARNING,
                                         "filePro: must set database 
directory first!\n");
                 RETURN_TRUE;
         }

         convert_to_long(rno);

         rnum = rno->value.lval;

     if (rnum < 0) {
         php_error(E_WARNING, "filepro: parameters out of range");
                 RETURN_TRUE;
     }

     offset = (rnum + 1) * (FP_GLOBAL(fp_keysize) + 20) ; /* Record location */

         /* Now read the record in */
         sprintf(workbuf, "%s/key", FP_GLOBAL(fp_database));

         if (PG(safe_mode) && (!php_checkuid(workbuf, 2))) {
                 RETURN_TRUE;
         }

         if (php_check_open_basedir(workbuf)) {
                 RETURN_TRUE;
         }

         if (!(fp = V_FOPEN(workbuf, "r"))) {
                 php_error(E_WARNING, "filePro: cannot open key: [%d] %s",
                                         errno, strerror(errno));
             fclose(fp);
                 RETURN_TRUE;
         }
     fseek(fp, offset, SEEK_SET);
         if (fread(readbuf, 1, 1, fp) != 1) {
         php_error(E_WARNING, "filePro: cannot read data: [%d] %s",
                                         errno, strerror(errno));
             fclose(fp);
                 RETURN_TRUE;
     }

         if( readbuf[0] ){
                 fclose(fp);
                 RETURN_FALSE;
         }
         fclose(fp);
         RETURN_TRUE;
}

#endif

/*
  * Local variables:
  * tab-width: 4
  * c-basic-offset: 4
  * End:
  */

===========================================================
Michael Gile                                  [EMAIL PROTECTED]
President                                     (518)435-0682
Web Services Group                       http://www.wsg.net  


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to