~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to sched/file_upload_handler.cpp

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
//
21
21
 
22
22
#include "config.h"
23
 
#include <cstdio>
24
23
#include <cstdlib>
25
24
#include <cstring>
26
25
#include <ctime>
30
29
#include <unistd.h>
31
30
#include <csignal>
32
31
#include <fcntl.h>
 
32
#include <string>
 
33
 
 
34
#ifdef _USING_FCGI_
 
35
#include "boinc_fcgi.h"
 
36
#else
 
37
#include <cstdio>
 
38
#endif
33
39
 
34
40
#include "crypt.h"
35
41
#include "parse.h"
36
42
#include "util.h"
37
43
#include "error_numbers.h"
 
44
#include "str_util.h"
38
45
#include "filesys.h"
 
46
#include "svn_version.h"
39
47
 
40
48
#include "sched_config.h"
41
49
#include "sched_util.h"
42
50
 
43
 
#ifdef _USING_FCGI_
44
 
#include "boinc_fcgi.h"
45
 
#endif
46
51
#include "sched_msgs.h"
47
52
 
48
53
#define ERR_TRANSIENT   true
49
54
#define ERR_PERMANENT   false
50
55
 
51
56
char this_filename[256];
 
57
double start_time();
52
58
 
53
59
struct FILE_INFO {
54
60
    char name[256];
215
221
        to_write=n;
216
222
        while (to_write > 0) {
217
223
            ssize_t ret = write(fd, buf+n-to_write, to_write);
218
 
            if (ret < 0) { 
 
224
            if (ret < 0) {
219
225
                close(fd);
220
226
                const char* errmsg;
221
227
                if (errno == ENOSPC) {
326
332
        if (parse_double(buf, "<nbytes>", nbytes)) continue;
327
333
        if (parse_str(buf, "<md5_cksum>", temp, sizeof(temp))) continue;
328
334
        if (match_tag(buf, "<data>")) {
329
 
            if (nbytes <= 0) {
 
335
            if (nbytes < 0) {
330
336
                return return_error(ERR_PERMANENT, "nbytes missing or negative");
331
337
            }
332
338
 
363
369
                path, true
364
370
            );
365
371
            if (retval) {
366
 
                log_messages.printf(MSG_CRITICAL, 
 
372
                log_messages.printf(MSG_CRITICAL,
367
373
                    "Failed to find/create directory for file '%s' in '%s'\n",
368
374
                    file_info.name, config.upload_dir
369
375
                );
427
433
        file_name, config.upload_dir, config.uldl_dir_fanout, path
428
434
    );
429
435
    if (retval) {
430
 
        log_messages.printf(MSG_CRITICAL, 
 
436
        log_messages.printf(MSG_CRITICAL,
431
437
            "Failed to find/create directory for file '%s' in '%s'.\n",
432
438
            file_name, config.upload_dir
433
439
        );
472
478
        return return_error(ERR_TRANSIENT,
473
479
            "[%s] locked by file_upload_handler PID=%d", file_name, pid
474
480
        );
475
 
    } 
 
481
    }
476
482
    // file exists, writable, not locked by anyone else, so return length.
477
483
    //
478
484
    retval = stat(path, &sbuf);
503
509
    int major, minor, release, retval=0;
504
510
    bool got_version = true;
505
511
    bool did_something = false;
 
512
    double start_time = dtime();
506
513
 
507
514
#ifdef _USING_FCGI_
508
515
    log_messages.set_indent_level(1);
546
553
        return return_error(ERR_TRANSIENT, "no command");
547
554
    }
548
555
 
549
 
    log_messages.printf(MSG_DEBUG,
550
 
        "elapsed time %f seconds\n", elapsed_wallclock_time()
551
 
    );
 
556
    log_messages.printf(MSG_DEBUG, "elapsed time %f seconds\n", dtime()-start_time);
552
557
 
553
558
    return retval;
554
559
}
563
568
    FCGI_FILE *f = FCGI::fopen(buf, "r");
564
569
#endif
565
570
    if (!f) return -1;
 
571
#ifdef _USING_FCGI_
 
572
    retval = scan_key_hex(FCGI_ToFILE(f), (KEY*)&key, sizeof(key));
 
573
#else
566
574
    retval = scan_key_hex(f, (KEY*)&key, sizeof(key));
 
575
#endif
567
576
    fclose(f);
568
577
    if (retval) return retval;
569
578
    return 0;
575
584
        sprintf(buffer, "FILE=%s (%.0f bytes left) ", this_filename, bytes_left);
576
585
    }
577
586
    log_messages.printf(MSG_CRITICAL,
578
 
        "%sIP=%s caught signal %d [%s] elapsed time %f seconds\n",
 
587
        "%sIP=%s caught signal %d [%s]\n",
579
588
        buffer, get_remote_addr(),
580
 
        signal_num, strsignal(signal_num), elapsed_wallclock_time()
 
589
        signal_num, strsignal(signal_num)
581
590
    );
582
591
 
583
592
    // there is no point in trying to return an error.
585
594
    // so a write to stdout will just generate a SIGPIPE
586
595
    //
587
596
    // return_error(ERR_TRANSIENT, "while downloading %s server caught signal %d", this_filename, signal_num);
588
 
    exit(1);
 
597
    _exit(1);
589
598
}
590
599
 
591
600
void installer() {
604
613
    signal(SIGTERM, boinc_catch_signal); // terminate process
605
614
}
606
615
 
607
 
int main() {
 
616
void usage(char *name) {
 
617
    fprintf(stderr,
 
618
        "This is the BOINC file upload handler.\n"
 
619
        "It receives the results from the clients\n"
 
620
        "and puts them on the file server.\n\n"
 
621
        "Normally this is run as a CGI program.\n\n"
 
622
        "Usage: %s [OPTION]...\n\n"
 
623
        "Options:\n"
 
624
        "  [ -h | --help ]        Show this help text.\n"
 
625
        "  [ -v | --version ]     Show version information.\n",
 
626
        name
 
627
    );
 
628
}
 
629
 
 
630
int main(int argc, char *argv[]) {
608
631
    int retval;
609
632
    R_RSA_PUBLIC_KEY key;
610
633
    char log_path[256];
611
634
#ifdef _USING_FCGI_
612
635
    unsigned int counter=0;
613
636
#endif
614
 
    elapsed_wallclock_time();
 
637
 
 
638
    for(int c = 1; c < argc; c++) {
 
639
        std::string option(argv[c]);
 
640
        if(option == "-v" || option == "--version") {
 
641
            printf("%s\n", SVN_VERSION);
 
642
            exit(0);
 
643
        } else if(option == "-h" || option == "--help") {
 
644
            usage(argv[0]);
 
645
            exit(0);
 
646
        } else if (option.length()){
 
647
            fprintf(stderr, "unknown command line argument: %s\n\n", argv[c]);
 
648
            usage(argv[0]);
 
649
            exit(1);
 
650
        }
 
651
    }
615
652
 
616
653
    installer();
617
654
 
618
655
    get_log_path(log_path, "file_upload_handler.log");
619
656
#ifndef _USING_FCGI_
620
657
    if (!freopen(log_path, "a", stderr)) {
621
 
        fprintf(stderr, "Can't open log file\n");
622
 
        return_error(ERR_TRANSIENT, "can't open log file");
 
658
        fprintf(stderr, "Can't open log file '%s' (errno: %d)\n",
 
659
            log_path, errno
 
660
        );
 
661
        return_error(ERR_TRANSIENT, "can't open log file '%s' (errno: %d)",
 
662
            log_path, errno
 
663
        );
623
664
        exit(1);
624
665
    }
625
666
#else
633
674
    }
634
675
#endif
635
676
 
636
 
    retval = config.parse_file("..");
 
677
    retval = config.parse_file();
637
678
    if (retval) {
 
679
        fprintf(stderr, "Can't parse config.xml: %s\n", boincerror(retval));
 
680
        return_error(ERR_TRANSIENT,
 
681
            "can't parse config file", log_path, errno
 
682
        );
638
683
        exit(1);
639
684
    }
640
685
 
641
686
    log_messages.pid = getpid();
642
687
    log_messages.set_debug_level(config.fuh_debug_level);
643
688
 
644
 
    if (boinc_file_exists("../stop_upload")) {
 
689
    if (boinc_file_exists(config.project_path("stop_upload"))) {
645
690
        return_error(ERR_TRANSIENT, "Maintenance underway: file uploads are temporarily disabled.");
646
691
        exit(1);
647
692
    }
655
700
    }
656
701
 
657
702
#ifdef _USING_FCGI_
658
 
  while(FCGI_Accept() >= 0) {
659
 
    counter++;
660
 
    //fprintf(stderr, "file_upload_handler (FCGI): counter: %d\n", counter);
661
 
    log_messages.set_indent_level(0);
 
703
    while(FCGI_Accept() >= 0) {
 
704
        counter++;
 
705
        //fprintf(stderr, "file_upload_handler (FCGI): counter: %d\n", counter);
 
706
        log_messages.set_indent_level(0);
662
707
#endif
663
 
    handle_request(stdin, key);
 
708
        handle_request(stdin, key);
664
709
#ifdef _USING_FCGI_
665
 
    // flush log for FCGI, otherwise it just buffers a lot
666
 
    log_messages.flush();
667
 
  }
668
 
  // when exiting, write headers back to apache so it won't complain
669
 
  // about "incomplete headers"
670
 
  fprintf(stdout,"Content-type: text/plain\n\n");
 
710
        // flush log for FCGI, otherwise it just buffers a lot
 
711
        log_messages.flush();
 
712
    }
 
713
    // when exiting, write headers back to apache so it won't complain
 
714
    // about "incomplete headers"
 
715
    fprintf(stdout,"Content-type: text/plain\n\n");
671
716
#endif
672
717
    return 0;
673
718
}
674
719
 
675
 
const char *BOINC_RCSID_470a0d4d11 = "$Id: file_upload_handler.cpp 16069 2008-09-26 18:20:24Z davea $";
 
720
const char *BOINC_RCSID_470a0d4d11 = "$Id: file_upload_handler.cpp 21181 2010-04-15 03:13:56Z davea $";