IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Aug 7, 2009, 12:45:24 PM (17 years ago)
Author:
eugene
Message:

update from mainline

Location:
branches/eam_branches/20090715
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715

  • branches/eam_branches/20090715/Nebulous/nebclient/src/nebclient.c

    r24289 r25022  
    5151static char *nullstrncpy(char *dest, const char *src, size_t n);
    5252
     53
    5354nebServer *nebServerAlloc(const char *endpoint)
    5455{
    55     nebServer       *server;
    56 
    57     server          = xmalloc(sizeof(nebServer));
     56    nebServer *server = xmalloc(sizeof(nebServer));
    5857
    5958    if (endpoint) {
     
    7776}
    7877
     78
    7979void nebServerFree(nebServer *server)
    8080{
     
    9292}
    9393
     94
    9495char *nebCreate(nebServer *server, const char *key, const char *volume, char **URI)
    9596{
     97    REQUIRE_SERVER;
     98
     99    if (!key) {
     100        nebSetErr(server, "parameter 'key' may not be NULL");
     101
     102        return NULL;
     103    }
     104
    96105    struct ns1__create_USCOREobjectResponse response;
    97     char            *filename;
    98 
    99     REQUIRE_SERVER;
    100 
    101     if (!key) {
    102         nebSetErr(server, "parameter 'key' may not be NULL");
    103 
    104         return NULL;
    105     }
    106 
    107106    if (soap_call_ns1__create_USCOREobject(server->soap, server->endpoint, NULL,
    108107            (char *)key, (char *)volume, (char **)&response) != SOAP_OK) {
     
    117116    }
    118117
     118    char *filename;
    119119    if (!nebParseURI(server, (char *)response.result, &filename)) {
    120120        nebSetErr(server, "can not parse URI");
     121        nebFree(filename);
     122
    121123        return NULL;
    122124    }
     
    131133}
    132134
     135
    133136int nebOpenCreate(nebServer *server, const char *key, const char *volume, char **URI)
    134137{
    135     char            *filename;
    136     int             file;
    137 
    138     REQUIRE_SERVER;
    139 
    140     if (!key) {
    141         nebSetErr(server, "parameter 'key' may not be NULL");
    142 
    143         return -1;
    144     }
    145 
    146     filename = nebCreate(server, key, volume, URI);
    147 
    148     file = open(filename, O_RDWR|O_TRUNC, 0660);
     138    REQUIRE_SERVER;
     139
     140    if (!key) {
     141        nebSetErr(server, "parameter 'key' may not be NULL");
     142
     143        return -1;
     144    }
     145
     146    char *filename = nebCreate(server, key, volume, URI);
     147    if (!filename) {
     148        return -1;
     149    }
     150
     151    int file = open(filename, O_RDWR|O_TRUNC, 0660);
    149152    if (file == -1) {
    150153        nebSetErr(server, "can not open %s: %s", filename, strerror(errno));
     
    159162}
    160163
     164
    161165bool nebReplicate(nebServer *server, const char *key, const char *volume, char **URI)
    162166{
    163     struct ns1__replicate_USCOREobjectResponse response;
    164     char            *filename;
    165     int             sourceFH, destFH;
    166 
    167167    REQUIRE_SERVER;
    168168
     
    177177    // we don't do this, it's possible that open will find & open the new
    178178    // instance that we're in the process of creating
    179     sourceFH = nebOpen(server, (char *)key, NEB_READ);
     179    int sourceFH = nebOpen(server, (char *)key, NEB_READ);
    180180    if (sourceFH == -1) {
    181181        nebSetErr(server, "can not open key %s", key);
    182         nebFree(filename);
    183182
    184183        return false;
     
    186185
    187186    // ask the server for a new instance attached to our key
     187    struct ns1__replicate_USCOREobjectResponse response;
    188188    if (soap_call_ns1__replicate_USCOREobject(server->soap, server->endpoint,
    189189            NULL, (char *)key, (char *)volume, (char **)&response) != SOAP_OK) {
     
    193193    }
    194194
     195    char *filename = NULL;
    195196    if (!nebParseURI(server, (char *)response.result, &filename)) {
    196197        nebSetErr(server, "can not parse URI");
     
    199200    }
    200201
    201     destFH = open(filename, O_RDWR|O_TRUNC, 0660);
     202    int destFH = open(filename, O_RDWR|O_TRUNC, 0660);
    202203    if (destFH == -1) {
    203204        nebSetErr(server, "can not open %s: %s\n", filename, strerror(errno));
     
    234235}
    235236
     237
    236238bool nebCull(nebServer *server, const char *key)
    237239{
    238     nebObjectInstances *locations;
    239 
    240     REQUIRE_SERVER;
    241 
    242     if (!key) {
    243         nebSetErr(server, "parameter 'key' may not be NULL");
    244 
    245         return false;
    246     }
    247 
    248     locations = nebFindInstances(server, key, NULL);
     240    REQUIRE_SERVER;
     241
     242    if (!key) {
     243        nebSetErr(server, "parameter 'key' may not be NULL");
     244
     245        return false;
     246    }
     247
     248    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
    249249    if (!locations || locations->n <= 1) {
    250250        nebSetErr(server, "can not cull - not enough instances");
     251        if (locations) {
     252            nebObjectInstancesFree(locations);
     253        }
    251254
    252255        return false;
     
    264267}
    265268
     269
    266270bool nebLock(nebServer *server, const char *key, nebRW flag)
    267271{
    268     time_t          endtime;
    269     char            *type;
    270     int             response;
    271 
    272     REQUIRE_SERVER;
    273 
    274     if (!key) {
    275         nebSetErr(server, "parameter 'key' may not be NULL");
    276 
    277         return false;
    278     }
    279 
    280     type = flag == NEB_READ ? "read" : "write";
    281 
    282     endtime = time(NULL) + LOCK_TIMEOUT;
     272    REQUIRE_SERVER;
     273
     274    if (!key) {
     275        nebSetErr(server, "parameter 'key' may not be NULL");
     276
     277        return false;
     278    }
     279
     280    char *type = flag == NEB_READ ? "read" : "write";
     281
     282    time_t endtime = time(NULL) + LOCK_TIMEOUT;
    283283
    284284    while (time(NULL) < endtime) {
     285        int response;
    285286        if (soap_call_ns1__lock_USCOREobject(server->soap, server->endpoint,
    286287            NULL, (char *)key, type, &response) != SOAP_OK) {
     
    302303}
    303304
     305
    304306bool nebUnlock(nebServer *server, const char *key, nebRW flag)
    305307{
    306     char            *type;
    307     int             response;
    308 
    309     REQUIRE_SERVER;
    310 
    311     if (!key) {
    312         nebSetErr(server, "parameter 'key' may not be NULL");
    313 
    314         return false;
    315     }
    316 
    317     type = flag == NEB_READ ? "read" : "write";
    318 
     308    REQUIRE_SERVER;
     309
     310    if (!key) {
     311        nebSetErr(server, "parameter 'key' may not be NULL");
     312
     313        return false;
     314    }
     315
     316    char *type = flag == NEB_READ ? "read" : "write";
     317
     318    int response;
    319319    if (soap_call_ns1__unlock_USCOREobject(server->soap, server->endpoint,
    320320        NULL, (char *)key, type, &response) != SOAP_OK) {
     
    466466nebObjectInstances *nebFindInstances(nebServer *server, const char *key, const char *volume)
    467467{
     468    REQUIRE_SERVER;
     469
     470    if (!key) {
     471        nebSetErr(server, "parameter 'key' may not be NULL");
     472
     473        return NULL;
     474    }
     475
    468476    struct ns1__find_USCOREinstancesResponse response;
    469     int             resultElements = 0;
    470     char            **resultArray;
    471     nebObjectInstances *locations = NULL;
    472 
    473     REQUIRE_SERVER;
    474 
    475     if (!key) {
    476         nebSetErr(server, "parameter 'key' may not be NULL");
    477 
    478         return NULL;
    479     }
    480 
    481477    // FIXME is this leaking memory when response goes out of scope?  the gsoap
    482478    // manual seems to 'suggest' that this is temporary data that gets cleaed
     
    488484    }
    489485
    490     resultElements = response.result->__size;
    491 
     486    int resultElements = response.result->__size;
     487
     488    nebObjectInstances *locations = NULL;
    492489    if (resultElements) {
    493490        locations = xmalloc(sizeof(nebObjectInstances));
    494491        locations->n = resultElements;
    495492       
    496         resultArray    = response.result->__ptr;
     493        char **resultArray = response.result->__ptr;
    497494
    498495        locations->URI = xmalloc(sizeof(char*) * resultElements);
     
    508505}
    509506
     507
    510508void nebObjectInstancesFree(nebObjectInstances *locations)
    511509{
     
    521519}
    522520
     521
    523522char *nebFind(nebServer *server, const char *key)
    524523{
    525     nebObjectInstances *locations;
    526     char            *filename;
    527 
    528524    REQUIRE_SERVER;
    529525
     
    534530    }
    535531   
    536     locations = nebFindInstances(server, key, NULL);
     532    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
    537533    if (!locations) {
    538534        if (!strstr(nebErr(server), "no instances on storage volume")) {
     
    548544    }
    549545
     546    char *filename;
    550547    if (!nebParseURI(server, locations->URI[0], &filename)) {
    551548        nebSetErr(server, "can not parse URI");
     
    560557}
    561558
     559
    562560int nebOpen(nebServer *server, const char *key, nebRW flag)
    563561{
    564     nebObjectInstances *locations;
    565     char            *filename;
    566     int             fh;
    567 
    568     REQUIRE_SERVER;
    569 
    570     if (!key) {
    571         nebSetErr(server, "parameter 'key' may not be NULL");
    572 
    573         return -1;
    574     }
    575 
    576     locations = nebFindInstances(server, key, NULL);
     562    REQUIRE_SERVER;
     563
     564    if (!key) {
     565        nebSetErr(server, "parameter 'key' may not be NULL");
     566
     567        return -1;
     568    }
     569
     570    nebObjectInstances *locations = nebFindInstances(server, key, NULL);
    577571    if (!locations) {
    578572        nebSetErr(server, "no instances found");
     
    581575    }
    582576
     577    char *filename;
    583578    if (!nebParseURI(server, locations->URI[0], &filename)) {
    584579        nebSetErr(server, "can not parse URI");
     
    588583    }
    589584
     585    int fh = 0;
    590586    if (flag == NEB_WRITE) {
    591587        if (locations->n > 1) {
     
    613609}
    614610
     611
    615612bool nebDelete(nebServer *server, const char *key)
    616613{
    617     nebObjectInstances *locations;
    618 
    619     REQUIRE_SERVER;
    620 
    621     if (!key) {
    622         nebSetErr(server, "parameter 'key' may not be NULL");
    623 
    624         return false;
    625     }
    626 
    627     locations = nebFindInstances(server, key, "any");
     614    REQUIRE_SERVER;
     615
     616    if (!key) {
     617        nebSetErr(server, "parameter 'key' may not be NULL");
     618
     619        return false;
     620    }
     621
     622    nebObjectInstances *locations = nebFindInstances(server, key, "any");
    628623    if (!locations) {
    629624        nebSetErr(server, "no instances found");
     
    646641}
    647642
     643
    648644bool nebCopy(nebServer *server, const char *key, const char *newKey)
    649645{
    650     int             sourceFH;
    651     int             destFH;
    652 
    653646    REQUIRE_SERVER;
    654647
     
    665658    }
    666659
    667     sourceFH = nebOpen(server, (char *)key, NEB_READ);
     660    int sourceFH = nebOpen(server, (char *)key, NEB_READ);
    668661    if (sourceFH < 0) {
    669662        // propigate nebOpen() error
     
    672665    }
    673666
    674     destFH = nebOpenCreate(server, newKey, NULL, NULL);
     667    int destFH = nebOpenCreate(server, newKey, NULL, NULL);
    675668    if (destFH < 0) {
    676669        // propigate nebCreate() error
     
    696689}
    697690
     691
    698692bool nebMove(nebServer *server, const char *key, const char *newKey)
    699693{
     
    723717}
    724718
     719
    725720bool nebSwap(nebServer *server, const char *key1, const char *key2)
    726721{
    727     struct ns1__create_USCOREobjectResponse response;
    728 
    729722    REQUIRE_SERVER;
    730723
     
    741734    }
    742735
     736    struct ns1__create_USCOREobjectResponse response;
    743737    if (soap_call_ns1__swap_USCOREobjects(server->soap, server->endpoint,
    744738            NULL, (char *)key1, (char *)key2, (char **)&response) != SOAP_OK) {
     
    749743}
    750744
     745
    751746bool nebDeleteInstance(nebServer *server, const char *key, const char *URI)
    752747{
    753     int             response;
    754     char            *filename;
    755     bool            status;
    756 
    757748    REQUIRE_SERVER;
    758749
     
    763754    }
    764755
     756    char *filename;
    765757    if (!nebParseURI(server, URI, &filename)) {
    766758        nebSetErr(server, "can not parse URI");
     
    769761    }
    770762
     763    int response;
    771764    if (soap_call_ns1__delete_USCOREinstance(server->soap, server->endpoint,
    772765        NULL, (char *)key, (char *)URI, &response) != SOAP_OK) {
     
    776769    }
    777770
     771    bool status;
    778772    if (response > 0) {
    779773        status = nebNukeFile(server, filename);
     
    787781}
    788782
     783
    789784nebObjectStat *nebStat(nebServer *server, const char *key)
    790785{
    791     struct ns1__stat_USCOREobjectResponse response;
    792     nebObjectStat   *stat;
    793     int             resultElements = 0;
    794     char            **resultArray = NULL;
    795 
    796786    REQUIRE_SERVER;
    797787
     
    802792    }
    803793
    804     stat = xmalloc(sizeof(nebObjectStat));
     794    nebObjectStat *stat = xmalloc(sizeof(nebObjectStat));
    805795
    806796    // FIXME is this leaking memory when response goes out of scope?  the gsoap
    807797    // manual seems to 'suggest' that this is temporary data that gets cleaed
    808798    // up on the next soap function call
     799    struct ns1__stat_USCOREobjectResponse response;
    809800    if (soap_call_ns1__stat_USCOREobject(server->soap, server->endpoint,
    810801            NULL, (char *)key, &response) != SOAP_OK) {
     
    813804    }
    814805
    815     resultElements = response.result->__size;
    816     resultArray    = response.result->__ptr;
    817 
    818     if (resultElements != 7) {
     806    int resultElements = response.result->__size;
     807    char **resultArray    = response.result->__ptr;
     808
     809    if (resultElements != 8) {
    819810        nebSetErr(server, "server didn't return the proper number of stat elements");
    820811        return NULL;
    821812    }
    822813
    823     nullstrncpy(stat->so_id, resultArray[0], 256);
    824     nullstrncpy(stat->ext_id, resultArray[1], 256);
    825     nullstrncpy(stat->read_lock, resultArray[2], 256);
     814    stat->so_id     = atol(resultArray[0]);
     815    stat->ext_id    = atol(resultArray[1]);
     816    stat->read_lock = atoi(resultArray[2]);
    826817    nullstrncpy(stat->write_lock, resultArray[3], 256);
    827818    nullstrncpy(stat->epoch, resultArray[4], 256);
    828819    nullstrncpy(stat->mtime, resultArray[5], 256);
    829     stat->instances = atoi(resultArray[6]);
     820    stat->available = atoi(resultArray[6]);
     821    stat->instances = atoi(resultArray[7]);
    830822
    831823    return stat;
     
    833825
    834826
     827void nebObjectStatFree(nebObjectStat *stat)
     828{
     829    if (!stat) {
     830        return;
     831    }
     832
     833    nebFree(stat);
     834}
     835
     836
    835837int nebChmod(nebServer *server, const char *key, mode_t mode)
    836838{
    837     int response;
    838 
    839839    REQUIRE_SERVER;
    840840
     
    848848    // manual seems to 'suggest' that this is temporary data that gets cleaed
    849849    // up on the next soap function call
     850    int response;
    850851    if (soap_call_ns1__chmod_USCOREobject(server->soap, server->endpoint,
    851852            NULL, (char *)key, mode, &response) != SOAP_OK) {
     
    858859
    859860
     861int nebPrune(nebServer *server, const char *key)
     862{
     863    REQUIRE_SERVER;
     864
     865    if (!key) {
     866        nebSetErr(server, "parameter 'key' may not be NULL");
     867
     868        return -1;
     869    }
     870
     871    // FIXME is this leaking memory when response goes out of scope?  the gsoap
     872    // manual seems to 'suggest' that this is temporary data that gets cleaed
     873    // up on the next soap function call
     874    int response;
     875    if (soap_call_ns1__prune_USCOREobject(server->soap, server->endpoint,
     876            NULL, (char *)key, &response) != SOAP_OK) {
     877        nebSetServerErr(server);
     878        return -1;
     879    }
     880
     881    return response;
     882}
     883
     884
     885int nebThereCanBeOnlyOne(nebServer *server, const char *key, const char *volume)
     886{
     887    REQUIRE_SERVER;
     888
     889    if (!key) {
     890        nebSetErr(server, "parameter 'key' may not be NULL");
     891
     892        return -1;
     893    }
     894
     895    // first - strip off any inaccesible instances
     896    if (nebPrune(server, key) < 0 ) {
     897        // use the prune() method to also determine if $key is valid
     898        return -1;
     899    }
     900
     901    // check to see if there is an instance on $vol_name that should be the
     902    // sole survivor
     903    nebObjectInstances *locations = NULL;
     904    if (volume) {
     905        locations = nebFindInstances(server, key, NULL);
     906    }
     907
     908    long removed = 0;
     909    if (locations && locations->n) {
     910        nebObjectInstances *instances = nebFindInstances(server, key, NULL);
     911        for (long i = 0; i < instances->n; i++) {
     912            if (strcmp(locations->URI[0], instances->URI[i]) == 0) {
     913                continue;
     914            }
     915            if (!nebDeleteInstance(server, key, instances->URI[i])) {
     916                nebObjectInstancesFree(instances);
     917                nebObjectInstancesFree(locations);
     918                return -1;
     919            }
     920            removed++;
     921        }
     922        nebObjectInstancesFree(instances);
     923        nebObjectInstancesFree(locations);
     924    } else {
     925        nebObjectInstancesFree(locations);
     926        // nuke whatever
     927        nebObjectStat *stat = nebStat(server, key);
     928        if (!stat) {
     929            return -1;
     930        }
     931
     932        int available = stat->available;
     933        nebObjectStatFree(stat);
     934
     935        // start at one so cull() is called one less time then the # of
     936        // instances
     937        for (long i = 1; i < available; i++) {
     938            if (!nebCull(server, key)) {
     939                return -1;
     940            }
     941            removed++;
     942        }
     943    }
     944
     945    return removed;
     946}
     947
     948
    860949char *nebErr(nebServer *server)
    861950{
     
    863952}
    864953
     954
    865955void nebFree(void *ptr) {
     956    if (!ptr) { return; }
    866957    xfree(ptr);
    867958}
     
    870961static void p_nebSetErr(const char * filename, unsigned long lineno, const char *function, nebServer *server, const char *format, ...)
    871962{
    872     va_list         args;
    873     size_t          err_size;
    874     char            err_location[ERRBUF_SIZE];
    875     size_t          err_location_size;
    876 
    877     err_location_size = snprintf(err_location, ERRBUF_SIZE, "%s:%lu %s() - ",
     963    char err_location[ERRBUF_SIZE];
     964    size_t err_location_size = snprintf(err_location, ERRBUF_SIZE, "%s:%lu %s() - ",
    878965            filename, lineno, function);
    879966
     
    888975
    889976    while (1) {
     977        va_list args;
    890978        va_start(args, format);
    891979        // append error string after error location info
    892         err_size = vsnprintf(
     980        size_t err_size = vsnprintf(
    893981                server->err_buf + err_location_size,
    894982                server->err_buf_size - err_location_size,
     
    9141002}
    9151003
     1004
    9161005static void nebSetServerErr(nebServer *server)
    9171006{
    918     const char      **code;
    919     const char      **string;
    920 
    921     REQUIRE_SERVER;
    922 
    923     code   = soap_faultcode(server->soap);
    924     string = soap_faultstring(server->soap);
     1007    REQUIRE_SERVER;
     1008
     1009    const char **code   = soap_faultcode(server->soap);
     1010    const char **string = soap_faultstring(server->soap);
    9251011
    9261012    nebSetErr(server, "%s - %s", *code, *string);
    9271013}
     1014
    9281015
    9291016#if NEBCOPYFILE
    9301017static off_t nebCopyFile(nebServer *server, const char *source, const char *dest)
    9311018{
    932     int             sourceFH;
    933     int             destFH;
    934     off_t           bytesCopied;
    935 
    936     REQUIRE_SERVER;
    937 
    938     sourceFH = open(source, O_RDONLY);
     1019    REQUIRE_SERVER;
     1020
     1021    int sourceFH = open(source, O_RDONLY);
    9391022    if (sourceFH == -1) {
    9401023        nebSetErr(server, "can not open %s: %s", source, strerror(errno));
     
    9431026    }
    9441027
    945     destFH = open(dest, O_WRONLY|O_CREAT|O_CREAT, 0600);
     1028    int destFH = open(dest, O_WRONLY|O_CREAT|O_CREAT, 0600);
    9461029    if (destFH == -1) {
    9471030        nebSetErr(server, "can not open %s: %s", dest, strerror(errno));
     
    9501033    }
    9511034
    952     bytesCopied = nebCopyFilehandle(server, sourceFH, destFH);
     1035    off_t bytesCopied = nebCopyFilehandle(server, sourceFH, destFH);
    9531036    if (bytesCopied < 0) {
    9541037        return -1;
     
    9711054#endif
    9721055
     1056
    9731057static off_t nebCopyFilehandle(nebServer *server, int sourceFH, int destFH)
    9741058{
    975     off_t           bytesTotal;
    976     off_t           bytesRemaining;
    977     off_t           writeSize;
    978     char            writeBuf[64 * 1024];
     1059    REQUIRE_SERVER;
     1060
    9791061    struct stat     sourceStat;
    980 
    981     REQUIRE_SERVER;
    982 
    9831062    if(fstat(sourceFH, &sourceStat)) {
    9841063        nebSetErr(server, "can not stat filehandles: %s", strerror(errno));
     
    9881067
    9891068    // the size of the file to copied
    990     bytesTotal = sourceStat.st_size;
     1069    off_t bytesTotal = sourceStat.st_size;
    9911070
    9921071    /*
     
    9961075    */
    9971076
    998     bytesRemaining = bytesTotal;
     1077    off_t bytesRemaining = bytesTotal;
    9991078
    10001079    while (bytesRemaining) {
     1080        off_t writeSize;
     1081        char writeBuf[64 * 1024];
    10011082        if (bytesRemaining <= sizeof(writeBuf)) {
    10021083            writeSize = bytesRemaining;
     
    10231104}
    10241105
     1106
    10251107static size_t nebParseURI(nebServer *server, const char *URI, char **filename)
    10261108{
    1027     regex_t         myregex;
    1028     regmatch_t      mymatch[2];
    1029     char            errbuf[ERRBUF_SIZE];
    1030     char            *pattern = "^file://(.*)$";
    1031     int             status;
    1032     size_t          matchStart, matchEnd;
    1033     size_t          matchLength;
    1034     size_t          filename_size;
    1035 
    10361109    REQUIRE_SERVER;
    10371110
     
    10481121    }
    10491122
    1050     status = regcomp(&myregex, pattern, REG_EXTENDED);
     1123    regex_t myregex;
     1124    regmatch_t mymatch[2];
     1125    char *pattern = "^file://(.*)$";
     1126    char errbuf[ERRBUF_SIZE];
     1127
     1128    int status = regcomp(&myregex, pattern, REG_EXTENDED);
    10511129    if (status != 0) {
    10521130        regerror(status, &myregex, errbuf, ERRBUF_SIZE);
     
    10661144    regfree(&myregex);
    10671145
    1068     matchStart = (size_t)mymatch[1].rm_so;
    1069     matchEnd   = (size_t)mymatch[1].rm_eo;
    1070     matchLength = matchEnd - matchStart;
     1146    size_t matchStart = (size_t)mymatch[1].rm_so;
     1147    size_t matchEnd   = (size_t)mymatch[1].rm_eo;
     1148    size_t matchLength = matchEnd - matchStart;
    10711149
    10721150    if (matchStart == -1) {
     
    10741152    }
    10751153
    1076     filename_size = matchLength + 1;
     1154    size_t filename_size = matchLength + 1;
    10771155    *filename = xmalloc(filename_size);
    10781156
     
    10811159    return strlen(*filename);
    10821160}
     1161
    10831162
    10841163static bool nebNukeFile(nebServer *server, const char *filename)
     
    11001179    return true;
    11011180}
     1181
    11021182
    11031183static char *nullstrncpy(char *dest, const char *src, size_t n) {
     
    11071187    }
    11081188
     1189    if (!dest) {
     1190        dest = xmalloc(n + 1);
     1191    }
     1192
    11091193    return strncpy(dest, src, n);
    11101194}
Note: See TracChangeset for help on using the changeset viewer.