Annotation of embedaddon/php/ext/dba/libinifile/inifile.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2010 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Author: Marcus Boerger <helly@php.net>                               |
        !            16:    +----------------------------------------------------------------------+
        !            17:  */
        !            18: 
        !            19: /* $Id: inifile.c 293036 2010-01-03 09:23:27Z sebastian $ */
        !            20: 
        !            21: #ifdef HAVE_CONFIG_H
        !            22: #include "config.h"
        !            23: #endif
        !            24: 
        !            25: #include "php.h"
        !            26: #include "php_globals.h"
        !            27: #include "safe_mode.h"
        !            28: 
        !            29: #include <stdlib.h>
        !            30: #include <string.h>
        !            31: #include <errno.h>
        !            32: #if HAVE_UNISTD_H
        !            33: #include <unistd.h>
        !            34: #endif
        !            35: 
        !            36: #include "inifile.h"
        !            37: 
        !            38: /* ret = -1 means that database was opened for read-only
        !            39:  * ret = 0  success
        !            40:  * ret = 1  key already exists - nothing done
        !            41:  */
        !            42: 
        !            43: /* {{{ inifile_version */
        !            44: char *inifile_version() 
        !            45: {
        !            46:        return "1.0, $Revision: 293036 $";
        !            47: }
        !            48: /* }}} */ 
        !            49: 
        !            50: /* {{{ inifile_free_key */
        !            51: void inifile_key_free(key_type *key)
        !            52: {
        !            53:        if (key->group) {
        !            54:                efree(key->group);
        !            55:        }
        !            56:        if (key->name) {
        !            57:                efree(key->name);
        !            58:        }
        !            59:        memset(key, 0, sizeof(key_type));
        !            60: }
        !            61: /* }}} */
        !            62: 
        !            63: /* {{{ inifile_free_val */
        !            64: void inifile_val_free(val_type *val)
        !            65: {
        !            66:        if (val->value) {
        !            67:                efree(val->value);
        !            68:        }
        !            69:        memset(val, 0, sizeof(val_type));
        !            70: }
        !            71: /* }}} */
        !            72: 
        !            73: /* {{{ inifile_free_val */
        !            74: void inifile_line_free(line_type *ln)
        !            75: {
        !            76:        inifile_key_free(&ln->key);
        !            77:        inifile_val_free(&ln->val);
        !            78:        ln->pos = 0;
        !            79: }
        !            80: /* }}} */
        !            81: 
        !            82: /* {{{ inifile_alloc */
        !            83: inifile * inifile_alloc(php_stream *fp, int readonly, int persistent TSRMLS_DC)
        !            84: {
        !            85:        inifile *dba;
        !            86: 
        !            87:        if (!readonly) {
        !            88:                if (!php_stream_truncate_supported(fp)) {
        !            89:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't truncate this stream");
        !            90:                        return NULL;
        !            91:                }
        !            92:        }
        !            93:  
        !            94:        dba = pemalloc(sizeof(inifile), persistent);
        !            95:        memset(dba, 0, sizeof(inifile));
        !            96:        dba->fp = fp;
        !            97:        dba->readonly = readonly;
        !            98:        return dba;
        !            99: }
        !           100: /* }}} */
        !           101: 
        !           102: /* {{{ inifile_free */
        !           103: void inifile_free(inifile *dba, int persistent)
        !           104: {
        !           105:        if (dba) {
        !           106:                inifile_line_free(&dba->curr);
        !           107:                inifile_line_free(&dba->next);
        !           108:                pefree(dba, persistent);
        !           109:        }
        !           110: }
        !           111: /* }}} */
        !           112: 
        !           113: /* {{{ inifile_key_split */
        !           114: key_type inifile_key_split(const char *group_name)
        !           115: {
        !           116:        key_type key;
        !           117:        char *name;
        !           118:        
        !           119:        if (group_name[0] == '[' && (name = strchr(group_name, ']')) != NULL) {
        !           120:                key.group = estrndup(group_name+1, name - (group_name + 1));
        !           121:                key.name = estrdup(name+1);
        !           122:        } else {
        !           123:                key.group = estrdup("");
        !           124:                key.name = estrdup(group_name);
        !           125:        }
        !           126:        return key;
        !           127: }
        !           128: /* }}} */
        !           129: 
        !           130: /* {{{ inifile_key_string */
        !           131: char * inifile_key_string(const key_type *key)
        !           132: {
        !           133:        if (key->group && *key->group) {
        !           134:                char *result;
        !           135:                spprintf(&result, 0, "[%s]%s", key->group, key->name ? key->name : "");
        !           136:                return result;
        !           137:        } else if (key->name) {
        !           138:                return estrdup(key->name);
        !           139:        } else {
        !           140:                return NULL;
        !           141:        }
        !           142: }
        !           143: /* }}} */
        !           144: 
        !           145: /* {{{ etrim */
        !           146: static char *etrim(const char *str)
        !           147: {
        !           148:        char *val;
        !           149:        size_t l;
        !           150:        
        !           151:        if (!str) {
        !           152:                return NULL;
        !           153:        }
        !           154:        val = (char*)str;
        !           155:        while (*val && strchr(" \t\r\n", *val)) {
        !           156:                val++;
        !           157:        }
        !           158:        l = strlen(val);
        !           159:        while (l && (strchr(" \t\r\n", val[l-1]))) {
        !           160:                l--;
        !           161:        }
        !           162:        return estrndup(val, l);
        !           163: }
        !           164: /* }}} */
        !           165: 
        !           166: /* {{{ inifile_findkey
        !           167:  */
        !           168: static int inifile_read(inifile *dba, line_type *ln TSRMLS_DC) {
        !           169:        char *fline;
        !           170:        char *pos;
        !           171: 
        !           172:        inifile_val_free(&ln->val);
        !           173:        while ((fline = php_stream_gets(dba->fp, NULL, 0)) != NULL) {
        !           174:                if (fline) {
        !           175:                        if (fline[0] == '[') {
        !           176:                                /* A value name cannot start with '['
        !           177:                                 * So either we find a ']' or we found an error
        !           178:                                 */
        !           179:                                pos = strchr(fline+1, ']');
        !           180:                                if (pos) {
        !           181:                                        *pos = '\0';
        !           182:                                        inifile_key_free(&ln->key);
        !           183:                                        ln->key.group = etrim(fline+1);
        !           184:                                        ln->key.name = estrdup("");
        !           185:                                        ln->pos = php_stream_tell(dba->fp);
        !           186:                                        efree(fline);
        !           187:                                        return 1;
        !           188:                                } else {
        !           189:                                        efree(fline);
        !           190:                                        continue;
        !           191:                                }
        !           192:                        } else {
        !           193:                                pos = strchr(fline, '=');
        !           194:                                if (pos) {
        !           195:                                        *pos = '\0';
        !           196:                                        /* keep group or make empty if not existent */
        !           197:                                        if (!ln->key.group) {
        !           198:                                                ln->key.group = estrdup("");
        !           199:                                        }
        !           200:                                        if (ln->key.name) {
        !           201:                                                efree(ln->key.name);
        !           202:                                        }
        !           203:                                        ln->key.name = etrim(fline);
        !           204:                                        ln->val.value = etrim(pos+1);
        !           205:                                        ln->pos = php_stream_tell(dba->fp);
        !           206:                                        efree(fline);
        !           207:                                        return 1;
        !           208:                                } else {
        !           209:                                        /* simply ignore lines without '='
        !           210:                                         * those should be comments
        !           211:                                         */
        !           212:                                         efree(fline);
        !           213:                                         continue;
        !           214:                                }
        !           215:                        }
        !           216:                }
        !           217:        }
        !           218:        inifile_line_free(ln);
        !           219:        return 0;
        !           220: }
        !           221: /* }}} */
        !           222: 
        !           223: /* {{{ inifile_key_cmp */
        !           224: /* 0 = EQUAL
        !           225:  * 1 = GROUP-EQUAL,NAME-DIFFERENT
        !           226:  * 2 = DIFFERENT
        !           227:  */
        !           228: static int inifile_key_cmp(const key_type *k1, const key_type *k2 TSRMLS_DC)
        !           229: {
        !           230:        assert(k1->group && k1->name && k2->group && k2->name);
        !           231:        
        !           232:        if (!strcasecmp(k1->group, k2->group)) {
        !           233:                if (!strcasecmp(k1->name, k2->name)) {
        !           234:                        return 0;
        !           235:                } else {
        !           236:                        return 1;
        !           237:                }
        !           238:        } else {
        !           239:                return 2;
        !           240:        }
        !           241: }
        !           242: /* }}} */
        !           243: 
        !           244: /* {{{ inifile_fetch
        !           245:  */
        !           246: val_type inifile_fetch(inifile *dba, const key_type *key, int skip TSRMLS_DC) {
        !           247:        line_type ln = {{NULL,NULL},{NULL}};
        !           248:        val_type val;
        !           249:        int res, grp_eq = 0;
        !           250: 
        !           251:        if (skip == -1 && dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key TSRMLS_CC)) {
        !           252:                /* we got position already from last fetch */
        !           253:                php_stream_seek(dba->fp, dba->next.pos, SEEK_SET);
        !           254:        } else {
        !           255:                /* specific instance or not same key -> restart search */
        !           256:                /* the slow way: restart and seacrch */
        !           257:                php_stream_rewind(dba->fp);
        !           258:                inifile_line_free(&dba->next);
        !           259:        }
        !           260:        if (skip == -1) {
        !           261:                skip = 0;
        !           262:        }
        !           263:        while(inifile_read(dba, &ln TSRMLS_CC)) {
        !           264:                if (!(res=inifile_key_cmp(&ln.key, key TSRMLS_CC))) {
        !           265:                        if (!skip) {
        !           266:                                val.value = estrdup(ln.val.value ? ln.val.value : "");
        !           267:                                /* allow faster access by updating key read into next */
        !           268:                                inifile_line_free(&dba->next);
        !           269:                                dba->next = ln;
        !           270:                                dba->next.pos = php_stream_tell(dba->fp);
        !           271:                                return val;
        !           272:                        }
        !           273:                        skip--;
        !           274:                } else if (res == 1) {
        !           275:                        grp_eq = 1;
        !           276:                } else if (grp_eq) {
        !           277:                        /* we are leaving group now: that means we cannot find the key */
        !           278:                        break;
        !           279:                }
        !           280:        }
        !           281:        inifile_line_free(&ln);
        !           282:        dba->next.pos = php_stream_tell(dba->fp);
        !           283:        return ln.val;
        !           284: }
        !           285: /* }}} */
        !           286: 
        !           287: /* {{{ inifile_firstkey
        !           288:  */
        !           289: int inifile_firstkey(inifile *dba TSRMLS_DC) {
        !           290:        inifile_line_free(&dba->curr);
        !           291:        dba->curr.pos = 0;
        !           292:        return inifile_nextkey(dba TSRMLS_CC);
        !           293: }
        !           294: /* }}} */
        !           295: 
        !           296: /* {{{ inifile_nextkey
        !           297:  */
        !           298: int inifile_nextkey(inifile *dba TSRMLS_DC) {
        !           299:        line_type ln = {{NULL,NULL},{NULL}};
        !           300: 
        !           301:        /*inifile_line_free(&dba->next); ??? */
        !           302:        php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET);
        !           303:        ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : "");
        !           304:        inifile_read(dba, &ln TSRMLS_CC);
        !           305:        inifile_line_free(&dba->curr);
        !           306:        dba->curr = ln;
        !           307:        return ln.key.group || ln.key.name;
        !           308: }      
        !           309: /* }}} */
        !           310: 
        !           311: /* {{{ inifile_truncate
        !           312:  */
        !           313: static int inifile_truncate(inifile *dba, size_t size TSRMLS_DC)
        !           314: {
        !           315:        int res;
        !           316: 
        !           317:        if ((res=php_stream_truncate_set_size(dba->fp, size)) != 0) {
        !           318:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in ftruncate: %d", res);
        !           319:                return FAILURE;
        !           320:        }
        !           321:        php_stream_seek(dba->fp, size, SEEK_SET);
        !           322:        return SUCCESS;
        !           323: }
        !           324: /* }}} */
        !           325: 
        !           326: /* {{{ inifile_find_group
        !           327:  * if found pos_grp_start points to "[group_name]"
        !           328:  */
        !           329: static int inifile_find_group(inifile *dba, const key_type *key, size_t *pos_grp_start TSRMLS_DC) 
        !           330: {
        !           331:        int ret = FAILURE;
        !           332: 
        !           333:        php_stream_flush(dba->fp);
        !           334:        php_stream_seek(dba->fp, 0, SEEK_SET);
        !           335:        inifile_line_free(&dba->curr);
        !           336:        inifile_line_free(&dba->next);
        !           337: 
        !           338:        if (key->group && strlen(key->group)) {
        !           339:                int res;
        !           340:                line_type ln = {{NULL,NULL},{NULL}};
        !           341: 
        !           342:                res = 1;
        !           343:                while(inifile_read(dba, &ln TSRMLS_CC)) {
        !           344:                        if ((res=inifile_key_cmp(&ln.key, key TSRMLS_CC)) < 2) {
        !           345:                                ret = SUCCESS;
        !           346:                                break;
        !           347:                        }
        !           348:                        *pos_grp_start = php_stream_tell(dba->fp);
        !           349:                }
        !           350:                inifile_line_free(&ln);
        !           351:        } else {
        !           352:                *pos_grp_start = 0;
        !           353:                ret = SUCCESS;
        !           354:        }
        !           355:        if (ret == FAILURE) {
        !           356:                *pos_grp_start = php_stream_tell(dba->fp);
        !           357:        }
        !           358:        return ret;
        !           359: }
        !           360: /* }}} */
        !           361: 
        !           362: /* {{{ inifile_next_group
        !           363:  * only valid after a call to inifile_find_group
        !           364:  * if any next group is found pos_grp_start points to "[group_name]" or whitespace before that
        !           365:  */
        !           366: static int inifile_next_group(inifile *dba, const key_type *key, size_t *pos_grp_start TSRMLS_DC) 
        !           367: {
        !           368:        int ret = FAILURE;
        !           369:        line_type ln = {{NULL,NULL},{NULL}};
        !           370: 
        !           371:        *pos_grp_start = php_stream_tell(dba->fp);
        !           372:        ln.key.group = estrdup(key->group);
        !           373:        while(inifile_read(dba, &ln TSRMLS_CC)) {
        !           374:                if (inifile_key_cmp(&ln.key, key TSRMLS_CC) == 2) {
        !           375:                        ret = SUCCESS;
        !           376:                        break;
        !           377:                }
        !           378:                *pos_grp_start = php_stream_tell(dba->fp);
        !           379:        }
        !           380:        inifile_line_free(&ln);
        !           381:        return ret;
        !           382: }
        !           383: /* }}} */
        !           384: 
        !           385: /* {{{ inifile_copy_to
        !           386:  */
        !           387: static int inifile_copy_to(inifile *dba, size_t pos_start, size_t pos_end, inifile **ini_copy TSRMLS_DC)
        !           388: {
        !           389:        php_stream *fp;
        !           390:        
        !           391:        if (pos_start == pos_end) {
        !           392:                *ini_copy = NULL;
        !           393:                return SUCCESS;
        !           394:        }
        !           395:        if ((fp = php_stream_temp_create(0, 64 * 1024)) == NULL) {
        !           396:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create temporary stream");
        !           397:                *ini_copy = NULL;
        !           398:                return FAILURE;
        !           399:        }
        !           400: 
        !           401:        if ((*ini_copy = inifile_alloc(fp, 1, 0 TSRMLS_CC)) == NULL) {
        !           402:                /* writes error */
        !           403:                return FAILURE;
        !           404:        }
        !           405:        php_stream_seek(dba->fp, pos_start, SEEK_SET);
        !           406:        if (!php_stream_copy_to_stream(dba->fp, fp, pos_end - pos_start)) {
        !           407:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy group [%zu - %zu] to temporary stream", pos_start, pos_end);
        !           408:                return FAILURE;
        !           409:        } 
        !           410:        return SUCCESS;
        !           411: }
        !           412: /* }}} */
        !           413: 
        !           414: /* {{{ inifile_filter
        !           415:  * copy from to dba while ignoring key name (group must equal)
        !           416:  */
        !           417: static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRMLS_DC) 
        !           418: {
        !           419:        size_t pos_start = 0, pos_next = 0, pos_curr;
        !           420:        int ret = SUCCESS;
        !           421:        line_type ln = {{NULL,NULL},{NULL}};
        !           422: 
        !           423:        php_stream_seek(from->fp, 0, SEEK_SET);
        !           424:        php_stream_seek(dba->fp, 0, SEEK_END);
        !           425:        while(inifile_read(from, &ln TSRMLS_CC)) {
        !           426:                switch(inifile_key_cmp(&ln.key, key TSRMLS_CC)) {
        !           427:                case 0:
        !           428:                        pos_curr = php_stream_tell(from->fp);
        !           429:                        if (pos_start != pos_next) {
        !           430:                                php_stream_seek(from->fp, pos_start, SEEK_SET);
        !           431:                                if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) {
        !           432:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start);
        !           433:                                        ret = FAILURE;
        !           434:                                }
        !           435:                                php_stream_seek(from->fp, pos_curr, SEEK_SET);
        !           436:                        }
        !           437:                        pos_next = pos_start = pos_curr;
        !           438:                        break;
        !           439:                case 1:
        !           440:                        pos_next = php_stream_tell(from->fp);
        !           441:                        break;
        !           442:                case 2:
        !           443:                        /* the function is meant to process only entries from same group */
        !           444:                        assert(0);
        !           445:                        break;
        !           446:                }
        !           447:        }
        !           448:        if (pos_start != pos_next) {
        !           449:                php_stream_seek(from->fp, pos_start, SEEK_SET);
        !           450:                if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) {
        !           451:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start);
        !           452:                        ret = FAILURE;
        !           453:                }
        !           454:        }
        !           455:        inifile_line_free(&ln);
        !           456:        return SUCCESS;
        !           457: }
        !           458: /* }}} */
        !           459: 
        !           460: /* {{{ inifile_delete_replace_append
        !           461:  */
        !           462: static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append TSRMLS_DC) 
        !           463: {
        !           464:        size_t pos_grp_start, pos_grp_next;
        !           465:        inifile *ini_tmp = NULL;
        !           466:        php_stream *fp_tmp = NULL;
        !           467:        int ret;
        !           468: 
        !           469:        /* 1) Search group start
        !           470:         * 2) Search next group
        !           471:         * 3) If not append: Copy group to ini_tmp
        !           472:         * 4) Open temp_stream and copy remainder
        !           473:         * 5) Truncate stream
        !           474:         * 6) If not append AND key.name given: Filtered copy back from ini_tmp 
        !           475:         *    to stream. Otherwise the user wanted to delete the group.
        !           476:         * 7) Append value if given
        !           477:         * 8) Append temporary stream
        !           478:         */
        !           479: 
        !           480:        assert(!append || (key->name && value)); /* missuse */
        !           481: 
        !           482:        /* 1 - 3 */
        !           483:        inifile_find_group(dba, key, &pos_grp_start TSRMLS_CC);
        !           484:        inifile_next_group(dba, key, &pos_grp_next TSRMLS_CC);
        !           485:        if (append) {
        !           486:                ret = SUCCESS;
        !           487:        } else {
        !           488:                ret = inifile_copy_to(dba, pos_grp_start, pos_grp_next, &ini_tmp TSRMLS_CC);
        !           489:        }
        !           490: 
        !           491:        /* 4 */
        !           492:        if (ret == SUCCESS) {
        !           493:                fp_tmp = php_stream_temp_create(0, 64 * 1024);
        !           494:                if (!fp_tmp) {
        !           495:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not create temporary stream");
        !           496:                        ret = FAILURE;
        !           497:                } else {
        !           498:                        php_stream_seek(dba->fp, 0, SEEK_END);
        !           499:                        if (pos_grp_next != (size_t)php_stream_tell(dba->fp)) {
        !           500:                                php_stream_seek(dba->fp, pos_grp_next, SEEK_SET);
        !           501:                                if (!php_stream_copy_to_stream(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL)) {
        !           502:                                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy remainder to temporary stream");
        !           503:                                        ret = FAILURE;
        !           504:                                }
        !           505:                        }
        !           506:                }
        !           507:        }
        !           508:        
        !           509:        /* 5 */
        !           510:        if (ret == SUCCESS) {
        !           511:                if (!value || (key->name && strlen(key->name))) {
        !           512:                        ret = inifile_truncate(dba, append ? pos_grp_next : pos_grp_start TSRMLS_CC); /* writes error on fail */
        !           513:                }
        !           514:        }
        !           515: 
        !           516:        if (ret == SUCCESS) {
        !           517:                if (key->name && strlen(key->name)) {
        !           518:                        /* 6 */
        !           519:                        if (!append && ini_tmp) {
        !           520:                                ret = inifile_filter(dba, ini_tmp, key TSRMLS_CC);
        !           521:                        }
        !           522: 
        !           523:                        /* 7 */
        !           524:                        /* important: do not query ret==SUCCESS again: inifile_filter might fail but
        !           525:                         * however next operation must be done.
        !           526:                         */
        !           527:                        if (value) {
        !           528:                                if (pos_grp_start == pos_grp_next && key->group && strlen(key->group)) {
        !           529:                                        php_stream_printf(dba->fp TSRMLS_CC, "[%s]\n", key->group);
        !           530:                                }
        !           531:                                php_stream_printf(dba->fp TSRMLS_CC, "%s=%s\n", key->name, value->value ? value->value : "");
        !           532:                        }
        !           533:                }
        !           534:                
        !           535:                /* 8 */ 
        !           536:                /* important: do not query ret==SUCCESS again: inifile_filter might fail but
        !           537:                 * however next operation must be done.
        !           538:                 */
        !           539:                if (fp_tmp && php_stream_tell(fp_tmp)) {
        !           540:                        php_stream_seek(fp_tmp, 0, SEEK_SET);
        !           541:                        php_stream_seek(dba->fp, 0, SEEK_END);
        !           542:                        if (!php_stream_copy_to_stream(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL)) {
        !           543:                                php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Could not copy from temporary stream - ini file truncated");
        !           544:                                ret = FAILURE;
        !           545:                        }
        !           546:                }
        !           547:        }
        !           548: 
        !           549:        if (ini_tmp) {
        !           550:                php_stream_close(ini_tmp->fp);
        !           551:                inifile_free(ini_tmp, 0);
        !           552:        }
        !           553:        if (fp_tmp) {
        !           554:                php_stream_close(fp_tmp);
        !           555:        }
        !           556:        php_stream_flush(dba->fp);
        !           557:        php_stream_seek(dba->fp, 0, SEEK_SET);
        !           558: 
        !           559:        return ret;
        !           560: }
        !           561: /* }}} */
        !           562: 
        !           563: /* {{{ inifile_delete
        !           564:  */
        !           565: int inifile_delete(inifile *dba, const key_type *key TSRMLS_DC) 
        !           566: {
        !           567:        return inifile_delete_replace_append(dba, key, NULL, 0 TSRMLS_CC);
        !           568: }      
        !           569: /* }}} */
        !           570: 
        !           571: /* {{{ inifile_relace
        !           572:  */
        !           573: int inifile_replace(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) 
        !           574: {
        !           575:        return inifile_delete_replace_append(dba, key, value, 0 TSRMLS_CC);
        !           576: }
        !           577: /* }}} */
        !           578: 
        !           579: /* {{{ inifile_append
        !           580:  */
        !           581: int inifile_append(inifile *dba, const key_type *key, const val_type *value TSRMLS_DC) 
        !           582: {
        !           583:        return inifile_delete_replace_append(dba, key, value, 1 TSRMLS_CC);
        !           584: }
        !           585: /* }}} */
        !           586: 
        !           587: /*
        !           588:  * Local variables:
        !           589:  * tab-width: 4
        !           590:  * c-basic-offset: 4
        !           591:  * End:
        !           592:  * vim600: sw=4 ts=4 fdm=marker
        !           593:  * vim<600: sw=4 ts=4
        !           594:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>