Ignore:
Timestamp:
Mar 8, 2024, 3:59:07 AM (4 months ago)
Author:
Bruno Cornec
Message:

More compiler fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.3/mondo/src/common/libmondo-stream.c

    r3872 r3877  
    200200    return (retval);
    201201}
     202
     203
     204
     205/**
     206 * Start to write to the next tape. Assume the user has already inserted it.
     207 * @param bkpinfo The backup information structure. @c bkpinfo->media_device is the only field used.
     208 * @return 0 for success, nonzero for failure.
     209 */
     210int start_to_write_to_next_tape()
     211{
     212    int res = 0;
     213    char *command = NULL;
     214
     215    if (bkpinfo->media_device == NULL) {
     216        log_it("Unable to open out from NULL device");
     217        return (1);
     218    }
     219
     220    paranoid_pclose(g_tape_stream);
     221    sync();
     222    sync();
     223    sync();
     224    log_it("New tape requested.");
     225    insist_on_this_tape_number(g_current_media_number + 1); // will increment g_current_media, too
     226    if (bkpinfo->backup_media_type == cdstream) {
     227        mr_asprintf(command, "cdrecord -eject dev=%s speed=%d fs=24m -waiti - >> %s 2>> %s", bkpinfo->media_device, bkpinfo->cdrw_speed, MONDO_LOGFILE, MONDO_LOGFILE);
     228        log_it("Opening OUT to next CD with the command");
     229        log_it(command);
     230        log_it("Let's see what happens, shall we?");
     231        g_tape_stream = popen(command, "w");
     232        mr_free(command);
     233
     234        if (!g_tape_stream) {
     235            log_to_screen("Failed to openout to cdstream (fifo)");
     236            return (1);
     237        }
     238    } else {
     239        log_it("Opening OUT to next tape");
     240        if (!(g_tape_stream = open_device_via_buffer(bkpinfo->media_device, 'w', bkpinfo->internal_tape_block_size))) {
     241            log_OS_error(g_tape_fifo);
     242            log_to_screen("Cannot openin stream device");
     243            return (1);
     244        }
     245    }
     246    g_tape_posK = 0;
     247    g_sigpipe = FALSE;
     248    res += write_header_block_to_stream((off_t)0, "start-of-tape", BLK_START_OF_TAPE);  /* just in case */
     249    res += write_header_block_to_stream((off_t)0, "start-of-backup", BLK_START_OF_BACKUP);  /* just in case */
     250    return (res);
     251}
     252
     253
     254
     255/**
     256 * Decide whether we should start a new tape. This is TRUE if we've run out of tape
     257 * (got SIGPIPE) or look like we will.
     258 * @param mediasize The size of the tape in megabytes.
     259 * @param length_of_incoming_file The length of the file we're about to write, in bytes.
     260 * @bug This seems like it'll only work for media_size != autodetect, but Mondo only allows
     261 * autodetecting the size. Huh?
     262 */
     263
     264/* TODO: Should be reviewed for mediasize being a off_t ??? */
     265bool
     266should_we_write_to_next_tape(long mediasize,
     267                             off_t length_of_incoming_file)
     268{
     269    /*@ bool's ***************************************************** */
     270    bool we_need_a_new_tape = FALSE;
     271
     272    /*@ end vars *************************************************** */
     273
     274    if (mediasize == 0) {
     275        return (FALSE);
     276    }
     277    if (mediasize > 0 && (g_tape_posK >> 10 >= mediasize)) {
     278        log_it("mediasize = %ld", mediasize);
     279        we_need_a_new_tape = TRUE;
     280        log_to_screen("Should have started a new tape/CD already");
     281    }
     282    if ((g_tape_posK + length_of_incoming_file / 1024) >> 10 >=
     283        mediasize - (SLICE_SIZE * 4 / 1024)) {
     284        log_it("g_tape_posK = %ld\nmediasize = %ld\n", g_tape_posK,
     285               mediasize);
     286        we_need_a_new_tape = TRUE;
     287    }
     288    return (we_need_a_new_tape);
     289}
     290
     291
    202292
    203293
     
    354444
    355445
     446/**
     447 * Copy a file from the opened stream (CD or tape) to @p outfile.
     448 * @param outfile The file to write to.
     449 * @param size The size of the file in the input stream.
     450 * @return 0 for success, nonzero for failure.
     451 */
     452int
     453read_file_from_stream_to_file(char *outfile, long long size)
     454{
     455
     456    /*@ int ******************************************************** */
     457    int res;
     458
     459    /*@ end vars *************************************************** */
     460
     461    res = read_file_from_stream_FULL(outfile, NULL, size);
     462
     463    return (res);
     464}
     465
     466
     467
     468
    356469int read_EXAT_files_from_tape(long long *ptmp_size, char *tmp_fname,
    357470                              int *pctrl_chr, char *xattr_fname,
     
    419532    return (res);
    420533}
     534
     535
     536/**
     537 * Copy @p infile to the opened stream (CD or tape).
     538 * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used.
     539 * @param infile The file to write to the stream.
     540 * @return 0 for success, nonzero for failure.
     541 */
     542int write_file_to_stream_from_file(char *infile)
     543{
     544    /*@ buffers **************************************************** */
     545    char datablock[TAPE_BLOCK_SIZE];
     546    char *checksum = NULL;
     547    char *infile_basename;
     548
     549    /*@ int ******************************************************** */
     550    int retval = 0;
     551    int noof_blocks;
     552
     553    /*  unsigned int ch; */
     554    unsigned int crc16;
     555    unsigned int crctt;
     556
     557    /*@ pointers *************************************************** */
     558    FILE *fin;
     559    char *p;
     560
     561    /*@ long ******************************************************* */
     562    long bytes_to_read = 0;
     563    long i;
     564
     565    off_t filesize;
     566
     567#ifdef EXTRA_TAPE_CHECKSUMS
     568    int ch;
     569#endif
     570
     571    /*@ initialize ************************************************ */
     572    crc16 = 0;
     573    crctt = 0;
     574
     575
     576
     577    /*@ end vars *************************************************** */
     578
     579    infile_basename = strrchr(infile, '/');
     580    if (infile_basename) {
     581        infile_basename++;
     582    } else {
     583        infile_basename = infile;
     584    }
     585    filesize = length_of_file(infile);
     586    if (should_we_write_to_next_tape(bkpinfo->media_size, filesize)) {
     587        start_to_write_to_next_tape();
     588        write_backcatalog_to_tape();
     589    }
     590    p = strrchr(infile, '/');
     591    if (!p) {
     592        p = infile;
     593    } else {
     594        p++;
     595    }
     596    log_it("Writing file '%s' to tape (%ld KB)", p, (long) filesize >> 10);
     597    write_header_block_to_stream(filesize, infile_basename, BLK_START_FILE);
     598//go_here_to_restart_saving_of_file:
     599    if (!(fin = fopen(infile, "r"))) {
     600        log_OS_error(infile);
     601        return (1);
     602    }
     603    for (noof_blocks = 0; filesize > 0;
     604         noof_blocks++, filesize -= bytes_to_read) {
     605        if (filesize < TAPE_BLOCK_SIZE) {
     606            bytes_to_read = (long) filesize;
     607            for (i = 0; i < TAPE_BLOCK_SIZE; i++) {
     608                datablock[i] = '\0';
     609            }
     610        } else {
     611            bytes_to_read = TAPE_BLOCK_SIZE;
     612        }
     613        if (fread(datablock, 1, (size_t) bytes_to_read, fin)) {
     614            // FIXME
     615        }
     616        g_tape_posK +=
     617            fwrite(datablock, 1, /*bytes_to_read */
     618                   (size_t) TAPE_BLOCK_SIZE,
     619                   g_tape_stream) / 1024;
     620        if (g_sigpipe) {
     621            log_it("Sigpipe occurred recently. I'll start a new tape.");
     622            fclose(fin);
     623            g_sigpipe = FALSE;
     624            start_to_write_to_next_tape();
     625            write_backcatalog_to_tape();    // kinda-sorta recursive :)
     626            return (0);
     627        }
     628#ifdef EXTRA_TAPE_CHECKSUMS
     629        for (i = 0; i < bytes_to_read; i++) {
     630            ch = datablock[i];
     631            crc16 = updcrcr(crc16, (unsigned) ch);
     632            crctt = updcrc(crctt, (unsigned) ch);
     633        }
     634#endif
     635    }
     636    paranoid_fclose(fin);
     637    mr_asprintf(checksum, "%04x%04x", crc16, crctt);
     638    /* TODO: what does it do ??? */
     639    write_header_block_to_stream((off_t)g_current_media_number, checksum, BLK_STOP_FILE);
     640    mr_free(checksum);
     641
     642//  log_it("File '%s' written to tape.", infile);
     643    return (retval);
     644}
     645
     646
     647
     648
     649
     650
    421651
    422652
     
    566796}
    567797
    568 
    569 
    570 
    571 /**
    572  * Open the CD stream for input.
    573  * @param bkpinfo The backup information structure. Passed to openin_tape().
    574  * @return 0 for success, nonzero for failure.
    575  * @note Equivalent to openin_tape() for now, but don't count on this behavior.
    576  */
    577 int openin_cdstream()
    578 {
    579     return (openin_tape());
    580 }
    581 
    582 /**
    583  * FIFO used to read/write to the tape device.
    584  * @bug This seems obsolete now that we call an external @c buffer program. Please look onto this.
    585  */
    586 char g_tape_fifo[MAX_STR_LEN];
    587 
    588 
    589 
    590 int set_tape_block_size_with_mt(long internal_tape_block_size)
    591 {
    592     char *tmp = NULL;
    593     int res;
    594 
    595     if (bkpinfo->media_device == NULL) {
    596         return(1);
    597     }
    598 
    599     if (strncmp(bkpinfo->media_device, "/dev/", 5)) {
    600         log_msg(1, "Not using 'mt setblk'. This isn't an actual /dev entry.");
    601         return (0);
    602     }
    603     mr_asprintf(tmp, "mt -f %s setblk %ld", bkpinfo->media_device, internal_tape_block_size);
    604     res = run_program_and_log_output(tmp, 3);
    605     mr_free(tmp);
    606     return (res);
    607 }
    608 
    609 /**
    610  * Return the non-rewinding device when passed the normal one
    611  * @param tapedev The tape device to open for writing.
    612  * @note the caller needs to free the string returned
    613  */
    614 char *get_non_rewind_dev(char *tapedev)
    615 {
    616 
    617     char *ntapedev = NULL;
    618     char *p = NULL;
    619     char *q = NULL;
    620     char *r = NULL;
    621 
    622     ntapedev = (char *)mr_malloc(strlen(tapedev)+2*sizeof(char));
    623     p = strrchr(tapedev,'/');
    624     if (p == NULL) {
    625         log_it("Didn't find a '/' in %s",tapedev);
    626         return(NULL);
    627     }
    628 
    629     /* Copy tapedev content up to the last / */
    630     q = tapedev;
    631     r = ntapedev;
    632     while (q != p) {
    633         *r = *q;
    634         r++;
    635         q++;
    636     }
    637     /* Copy the '/' */
    638     *r = *q;
    639     r++;
    640     q++;
    641     /* Adds a 'n' - non-rewinding */
    642     *r = 'n';
    643     r++;
    644     /* Copy the rest of tapedev */
    645     while (*q != '\0') {
    646         *r = *q;
    647         r++;
    648         q++;
    649     }
    650     *r = '\0';
    651     if (mt_says_tape_exists(ntapedev)) {
    652         log_it("Non-rewinding tape device is %s",ntapedev);
    653     } else {
    654         log_it("Unable to find non-rewinding tape device.");
    655         ntapedev = NULL;
    656     }
    657     return(ntapedev);
    658 }
    659 
    660 
    661 
    662 /**
    663  * Handle OBDR if we were asked to do so
    664  * @param tapedev The tape device to open for reading.
    665  */
    666 int skip_obdr(void)
    667 {
    668     char *command = NULL;
    669     int res = 0;
    670 
    671     if (bkpinfo->media_device == NULL) {
    672         return(1);
    673     }
    674 
    675     log_it("Skipping OBDR headers");
    676     mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device);
    677     res = run_program_and_log_output(command, 1);
    678     paranoid_free(command);
    679 
    680     mr_asprintf(command, "mt -f %s fsf 2",bkpinfo->media_device);
    681     res = run_program_and_log_output(command, 1);
    682     paranoid_free(command);
    683 
    684     set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
    685     return(res);
    686 }
    687 
    688 /**
    689  * Handle OBDR if we were asked to do so
    690  * @param tapedev The tape device to open for writing.
    691  * @return 0 for success, nonzero for failure.
    692  * @note This should be called ONLY from backup processes. It will OVERWRITE ANY
    693  * EXISTING DATA on the tape!
    694  */
    695 int create_obdr(void)
    696 {
    697 
    698     char *command = NULL;
    699     int res = 0;
    700 
    701     if (bkpinfo->media_device == NULL) {
    702         return(1);
    703     }
    704 
    705     log_it("Creating OBDR headers");
    706     /* OBDR: First block 10 kB of zero bs = 512 */
    707     mr_asprintf(command, "mt -f %s compression off",bkpinfo->media_device);
    708     res = run_program_and_log_output(command, 1);
    709     paranoid_free(command);
    710 
    711     mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device);
    712     res += run_program_and_log_output(command, 1);
    713     paranoid_free(command);
    714 
    715     set_tape_block_size_with_mt(512);
    716 
    717     mr_asprintf(command, "dd if=/dev/zero of=%s bs=512 count=20",bkpinfo->media_device);
    718     res += run_program_and_log_output(command, 1);
    719     paranoid_free(command);
    720 
    721     /* OBDR: then ISO boot image bs = 2048 */
    722     set_tape_block_size_with_mt(2048);
    723 
    724     mr_asprintf(command, "dd if=%s of=%s bs=2048",MINDI_CACHE"/mindi.iso",bkpinfo->media_device);
    725     res += run_program_and_log_output(command, 1);
    726     paranoid_free(command);
    727 
    728     set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
    729 
    730     /* restore compression mode on */
    731     mr_asprintf(command, "mt -f %s compression on",bkpinfo->media_device);
    732     res = run_program_and_log_output(command, 1);
    733     paranoid_free(command);
    734 
    735     return(res);
    736 }
    737798
    738799
     
    871932
    872933
     934
     935/**
     936 * Open the CD stream for input.
     937 * @param bkpinfo The backup information structure. Passed to openin_tape().
     938 * @return 0 for success, nonzero for failure.
     939 * @note Equivalent to openin_tape() for now, but don't count on this behavior.
     940 */
     941int openin_cdstream()
     942{
     943    return (openin_tape());
     944}
     945
     946/**
     947 * FIFO used to read/write to the tape device.
     948 * @bug This seems obsolete now that we call an external @c buffer program. Please look onto this.
     949 */
     950char g_tape_fifo[MAX_STR_LEN];
     951
     952
     953
     954int set_tape_block_size_with_mt(long internal_tape_block_size)
     955{
     956    char *tmp = NULL;
     957    int res;
     958
     959    if (bkpinfo->media_device == NULL) {
     960        return(1);
     961    }
     962
     963    if (strncmp(bkpinfo->media_device, "/dev/", 5)) {
     964        log_msg(1, "Not using 'mt setblk'. This isn't an actual /dev entry.");
     965        return (0);
     966    }
     967    mr_asprintf(tmp, "mt -f %s setblk %ld", bkpinfo->media_device, internal_tape_block_size);
     968    res = run_program_and_log_output(tmp, 3);
     969    mr_free(tmp);
     970    return (res);
     971}
     972
     973/**
     974 * Return the non-rewinding device when passed the normal one
     975 * @param tapedev The tape device to open for writing.
     976 * @note the caller needs to free the string returned
     977 */
     978char *get_non_rewind_dev(char *tapedev)
     979{
     980
     981    char *ntapedev = NULL;
     982    char *p = NULL;
     983    char *q = NULL;
     984    char *r = NULL;
     985
     986    ntapedev = (char *)mr_malloc(strlen(tapedev)+2*sizeof(char));
     987    p = strrchr(tapedev,'/');
     988    if (p == NULL) {
     989        log_it("Didn't find a '/' in %s",tapedev);
     990        return(NULL);
     991    }
     992
     993    /* Copy tapedev content up to the last / */
     994    q = tapedev;
     995    r = ntapedev;
     996    while (q != p) {
     997        *r = *q;
     998        r++;
     999        q++;
     1000    }
     1001    /* Copy the '/' */
     1002    *r = *q;
     1003    r++;
     1004    q++;
     1005    /* Adds a 'n' - non-rewinding */
     1006    *r = 'n';
     1007    r++;
     1008    /* Copy the rest of tapedev */
     1009    while (*q != '\0') {
     1010        *r = *q;
     1011        r++;
     1012        q++;
     1013    }
     1014    *r = '\0';
     1015    if (mt_says_tape_exists(ntapedev)) {
     1016        log_it("Non-rewinding tape device is %s",ntapedev);
     1017    } else {
     1018        log_it("Unable to find non-rewinding tape device.");
     1019        ntapedev = NULL;
     1020    }
     1021    return(ntapedev);
     1022}
     1023
     1024
     1025
     1026/**
     1027 * Handle OBDR if we were asked to do so
     1028 * @param tapedev The tape device to open for reading.
     1029 */
     1030int skip_obdr(void)
     1031{
     1032    char *command = NULL;
     1033    int res = 0;
     1034
     1035    if (bkpinfo->media_device == NULL) {
     1036        return(1);
     1037    }
     1038
     1039    log_it("Skipping OBDR headers");
     1040    mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device);
     1041    res = run_program_and_log_output(command, 1);
     1042    paranoid_free(command);
     1043
     1044    mr_asprintf(command, "mt -f %s fsf 2",bkpinfo->media_device);
     1045    res = run_program_and_log_output(command, 1);
     1046    paranoid_free(command);
     1047
     1048    set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
     1049    return(res);
     1050}
     1051
     1052/**
     1053 * Handle OBDR if we were asked to do so
     1054 * @param tapedev The tape device to open for writing.
     1055 * @return 0 for success, nonzero for failure.
     1056 * @note This should be called ONLY from backup processes. It will OVERWRITE ANY
     1057 * EXISTING DATA on the tape!
     1058 */
     1059int create_obdr(void)
     1060{
     1061
     1062    char *command = NULL;
     1063    int res = 0;
     1064
     1065    if (bkpinfo->media_device == NULL) {
     1066        return(1);
     1067    }
     1068
     1069    log_it("Creating OBDR headers");
     1070    /* OBDR: First block 10 kB of zero bs = 512 */
     1071    mr_asprintf(command, "mt -f %s compression off",bkpinfo->media_device);
     1072    res = run_program_and_log_output(command, 1);
     1073    paranoid_free(command);
     1074
     1075    mr_asprintf(command, "mt -f %s rewind",bkpinfo->media_device);
     1076    res += run_program_and_log_output(command, 1);
     1077    paranoid_free(command);
     1078
     1079    set_tape_block_size_with_mt(512);
     1080
     1081    mr_asprintf(command, "dd if=/dev/zero of=%s bs=512 count=20",bkpinfo->media_device);
     1082    res += run_program_and_log_output(command, 1);
     1083    paranoid_free(command);
     1084
     1085    /* OBDR: then ISO boot image bs = 2048 */
     1086    set_tape_block_size_with_mt(2048);
     1087
     1088    mr_asprintf(command, "dd if=%s of=%s bs=2048",MINDI_CACHE"/mindi.iso",bkpinfo->media_device);
     1089    res += run_program_and_log_output(command, 1);
     1090    paranoid_free(command);
     1091
     1092    set_tape_block_size_with_mt(bkpinfo->internal_tape_block_size);
     1093
     1094    /* restore compression mode on */
     1095    mr_asprintf(command, "mt -f %s compression on",bkpinfo->media_device);
     1096    res = run_program_and_log_output(command, 1);
     1097    paranoid_free(command);
     1098
     1099    return(res);
     1100}
     1101
     1102
    8731103/**
    8741104 * Start writing to a CD stream.
     
    9481178}
    9491179return (0);
    950 }
    951 
    952 
    953 
    954 
    955 /**
    956  * Copy a file from the opened stream (CD or tape) to @p outfile.
    957  * @param outfile The file to write to.
    958  * @param size The size of the file in the input stream.
    959  * @return 0 for success, nonzero for failure.
    960  */
    961 int
    962 read_file_from_stream_to_file(char *outfile, long long size)
    963 {
    964 
    965     /*@ int ******************************************************** */
    966     int res;
    967 
    968     /*@ end vars *************************************************** */
    969 
    970     res = read_file_from_stream_FULL(outfile, NULL, size);
    971 
    972     return (res);
    973 }
    974 
    975 
    976 
    977 /**
    978  * Copy a file from the currently opened stream (CD or tape) to the stream indicated
    979  * by @p fout.
    980  * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used.
    981  * @param fout The stream to write the file to.
    982  * @param size The size of the file in bytes.
    983  * @return 0 for success, nonzero for failure.
    984  */
    985 int
    986 read_file_from_stream_to_stream(FILE * fout, long long size)
    987 {
    988 
    989     /*@ int ******************************************************** */
    990     int res;
    991 
    992     /*@ end vars *************************************************** */
    993 
    994     res = read_file_from_stream_FULL(NULL, fout, size);
    995 /*  fflush(g_tape_stream);
    996   fflush(fout);*/
    997     return (res);
    9981180}
    9991181
     
    11471329
    11481330/**
    1149  * Read a header block from the currently opened stream (CD or tape).
    1150  * This block indicates the length of the following file (if it's file-related)
    1151  * the filename (if it's file-related), and the block type.
    1152  * @param plen Where to put the length of the file. Valid only for file-related header blocks.
    1153  * @param filename Where to put the name of the file. Valid only for file-related header blocks.
    1154  * @param pcontrol_char Where to put the type of block (e.g. start-file, end-file, start-tape, ...)
    1155  * @return 0 for success, nonzero for failure.
    1156  * @note If you read a marker (@p pcontrol_char) you're not expecting, you can call wrong_marker().
     1331 * Copy a file from the currently opened stream (CD or tape) to the stream indicated
     1332 * by @p fout.
     1333 * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used.
     1334 * @param fout The stream to write the file to.
     1335 * @param size The size of the file in bytes.
     1336 * @return 0 for success, nonzero for failure.
    11571337 */
    11581338int
    1159 read_header_block_from_stream(long long *plen, char *filename,
    1160                               int *pcontrol_char)
    1161 {
    1162 
    1163     /*@ buffers ***************************************************** */
    1164     char *tempblock;
    1165     char *tmp = NULL;
    1166 
    1167     /*@ int ********************************************************* */
    1168     int i, retval;
     1339read_file_from_stream_to_stream(FILE * fout, long long size)
     1340{
     1341
     1342    /*@ int ******************************************************** */
     1343    int res;
    11691344
    11701345    /*@ end vars *************************************************** */
    11711346
    1172     tempblock = (char *) malloc((size_t) TAPE_BLOCK_SIZE);
    1173 
    1174     for (i = 0; i < (int) TAPE_BLOCK_SIZE; i++) {
    1175         tempblock[i] = 0;
    1176     }
    1177     while (!(*pcontrol_char = tempblock[7000])) {
    1178         g_tape_posK += fread(tempblock, 1, (size_t) TAPE_BLOCK_SIZE, g_tape_stream) / 1024;
    1179     }
    1180     memcpy((char *) plen, tempblock + 7001, sizeof(long long));
    1181     if (strcmp(tempblock + 6000 + *pcontrol_char, STR_HEADER)) {
    1182         log_it("Bad header block at %ld K", (long) g_tape_posK);
    1183     }
    1184     strcpy(filename, tempblock + 1000);
    1185     if (*pcontrol_char == BLK_ABORTED_BACKUP) {
    1186         log_to_screen("I can't verify an aborted backup.");
    1187         retval = 1;
    1188     } else {
    1189         retval = 0;
    1190     }
    1191     for (i = 1000; i < 1020; i++) {
    1192         if (tempblock[i] < 32 || tempblock[i] > 126) {
    1193             tempblock[i] = ' ';
    1194         }
    1195     }
    1196     tempblock[i] = '\0';
    1197     tmp = marker_to_string(*pcontrol_char);
    1198     log_msg(6, "%s (fname=%s, size=%ld K)", tmp, tempblock + 1000, (long) (*plen) >> 10);
    1199     mr_free(tmp);
    1200     paranoid_free(tempblock);
    1201     return (retval);
    1202 }
    1203 
    1204 
    1205 
    1206 /**
    1207  * Add specified file/slice to the internal catalog of all archives written.
    1208  * This lets us restart on a new CD/tape/whatever if it runs out of room. We just
    1209  * write the last [buffer size] MB from the catalog to the new tape, so we know
    1210  * we have @e all archives on some CD/tape/whatever.
    1211  * @param type The type of file we're cataloging (afioball, slice, something else)
    1212  * @param number The fileset number or biggiefile number.
    1213  * @param aux The slice number if it's a biggiefile, or any other additional info.
    1214  * @param fn The original full pathname of the file we're recording.
    1215  * @return The index of the record we just added.
    1216  */
    1217 int register_in_tape_catalog(t_archtype type, int number, long aux,
    1218                              char *fn)
    1219 {
    1220     int last;
    1221     char fname[MAX_TAPECAT_FNAME_LEN+1];
    1222     char *p;
    1223 
    1224     p = strrchr(fn, '/');
    1225     if (p) {
    1226         p++;
    1227     } else {
    1228         p = fn;
    1229     }
    1230     strncpy(fname, p, MAX_TAPECAT_FNAME_LEN);
    1231     fname[MAX_TAPECAT_FNAME_LEN] = '\0';
    1232     last = g_tapecatalog->entries;
    1233     if (last >= MAX_TAPECATALOG_ENTRIES) {
    1234         log_it
    1235             ("Warning - can't log #%d in tape catalog - too many entries already",
    1236              number);
    1237         return (-1);
    1238     }
    1239     g_tapecatalog->el[last].type = type;
    1240     g_tapecatalog->el[last].number = number;
    1241     g_tapecatalog->el[last].aux = aux;
    1242     g_tapecatalog->el[last].tape_posK = g_tape_posK;
    1243     strcpy(g_tapecatalog->el[last].fname, fname);
    1244     g_tapecatalog->entries++;
    1245     return (last);              // returns the index of the record we've jsut added
    1246 }
    1247 
    1248 
    1249 
    1250 
    1251 /**
    1252  * Decide whether we should start a new tape. This is TRUE if we've run out of tape
    1253  * (got SIGPIPE) or look like we will.
    1254  * @param mediasize The size of the tape in megabytes.
    1255  * @param length_of_incoming_file The length of the file we're about to write, in bytes.
    1256  * @bug This seems like it'll only work for media_size != autodetect, but Mondo only allows
    1257  * autodetecting the size. Huh?
    1258  */
    1259 
    1260 /* TODO: Should be reviewed for mediasize being a off_t ??? */
    1261 bool
    1262 should_we_write_to_next_tape(long mediasize,
    1263                              off_t length_of_incoming_file)
    1264 {
    1265     /*@ bool's ***************************************************** */
    1266     bool we_need_a_new_tape = FALSE;
    1267 
    1268     /*@ end vars *************************************************** */
    1269 
    1270     if (mediasize == 0) {
    1271         return (FALSE);
    1272     }
    1273     if (mediasize > 0 && (g_tape_posK >> 10 >= mediasize)) {
    1274         log_it("mediasize = %ld", mediasize);
    1275         we_need_a_new_tape = TRUE;
    1276         log_to_screen("Should have started a new tape/CD already");
    1277     }
    1278     if ((g_tape_posK + length_of_incoming_file / 1024) >> 10 >=
    1279         mediasize - (SLICE_SIZE * 4 / 1024)) {
    1280         log_it("g_tape_posK = %ld\nmediasize = %ld\n", g_tape_posK,
    1281                mediasize);
    1282         we_need_a_new_tape = TRUE;
    1283     }
    1284     return (we_need_a_new_tape);
     1347    res = read_file_from_stream_FULL(NULL, fout, size);
     1348/*  fflush(g_tape_stream);
     1349  fflush(fout);*/
     1350    return (res);
    12851351}
    12861352
     
    14481514
    14491515/**
    1450  * Start to write to the next tape. Assume the user has already inserted it.
    1451  * @param bkpinfo The backup information structure. @c bkpinfo->media_device is the only field used.
    1452  * @return 0 for success, nonzero for failure.
    1453  */
    1454 int start_to_write_to_next_tape()
    1455 {
    1456     int res = 0;
    1457     char *command = NULL;
    1458 
    1459     if (bkpinfo->media_device == NULL) {
    1460         log_it("Unable to open out from NULL device");
    1461         return (1);
    1462     }
    1463 
    1464     paranoid_pclose(g_tape_stream);
    1465     sync();
    1466     sync();
    1467     sync();
    1468     log_it("New tape requested.");
    1469     insist_on_this_tape_number(g_current_media_number + 1); // will increment g_current_media, too
    1470     if (bkpinfo->backup_media_type == cdstream) {
    1471         mr_asprintf(command, "cdrecord -eject dev=%s speed=%d fs=24m -waiti - >> %s 2>> %s", bkpinfo->media_device, bkpinfo->cdrw_speed, MONDO_LOGFILE, MONDO_LOGFILE);
    1472         log_it("Opening OUT to next CD with the command");
    1473         log_it(command);
    1474         log_it("Let's see what happens, shall we?");
    1475         g_tape_stream = popen(command, "w");
    1476         mr_free(command);
    1477 
    1478         if (!g_tape_stream) {
    1479             log_to_screen("Failed to openout to cdstream (fifo)");
    1480             return (1);
    1481         }
    1482     } else {
    1483         log_it("Opening OUT to next tape");
    1484         if (!(g_tape_stream = open_device_via_buffer(bkpinfo->media_device, 'w', bkpinfo->internal_tape_block_size))) {
    1485             log_OS_error(g_tape_fifo);
    1486             log_to_screen("Cannot openin stream device");
    1487             return (1);
    1488         }
    1489     }
    1490     g_tape_posK = 0;
    1491     g_sigpipe = FALSE;
    1492     res += write_header_block_to_stream((off_t)0, "start-of-tape", BLK_START_OF_TAPE);  /* just in case */
    1493     res += write_header_block_to_stream((off_t)0, "start-of-backup", BLK_START_OF_BACKUP);  /* just in case */
    1494     return (res);
     1516 * Read a header block from the currently opened stream (CD or tape).
     1517 * This block indicates the length of the following file (if it's file-related)
     1518 * the filename (if it's file-related), and the block type.
     1519 * @param plen Where to put the length of the file. Valid only for file-related header blocks.
     1520 * @param filename Where to put the name of the file. Valid only for file-related header blocks.
     1521 * @param pcontrol_char Where to put the type of block (e.g. start-file, end-file, start-tape, ...)
     1522 * @return 0 for success, nonzero for failure.
     1523 * @note If you read a marker (@p pcontrol_char) you're not expecting, you can call wrong_marker().
     1524 */
     1525int
     1526read_header_block_from_stream(long long *plen, char *filename,
     1527                              int *pcontrol_char)
     1528{
     1529
     1530    /*@ buffers ***************************************************** */
     1531    char *tempblock;
     1532    char *tmp = NULL;
     1533
     1534    /*@ int ********************************************************* */
     1535    int i, retval;
     1536
     1537    /*@ end vars *************************************************** */
     1538
     1539    tempblock = (char *) malloc((size_t) TAPE_BLOCK_SIZE);
     1540
     1541    for (i = 0; i < (int) TAPE_BLOCK_SIZE; i++) {
     1542        tempblock[i] = 0;
     1543    }
     1544    while (!(*pcontrol_char = tempblock[7000])) {
     1545        g_tape_posK += fread(tempblock, 1, (size_t) TAPE_BLOCK_SIZE, g_tape_stream) / 1024;
     1546    }
     1547    memcpy((char *) plen, tempblock + 7001, sizeof(long long));
     1548    if (strcmp(tempblock + 6000 + *pcontrol_char, STR_HEADER)) {
     1549        log_it("Bad header block at %ld K", (long) g_tape_posK);
     1550    }
     1551    strcpy(filename, tempblock + 1000);
     1552    if (*pcontrol_char == BLK_ABORTED_BACKUP) {
     1553        log_to_screen("I can't verify an aborted backup.");
     1554        retval = 1;
     1555    } else {
     1556        retval = 0;
     1557    }
     1558    for (i = 1000; i < 1020; i++) {
     1559        if (tempblock[i] < 32 || tempblock[i] > 126) {
     1560            tempblock[i] = ' ';
     1561        }
     1562    }
     1563    tempblock[i] = '\0';
     1564    tmp = marker_to_string(*pcontrol_char);
     1565    log_msg(6, "%s (fname=%s, size=%ld K)", tmp, tempblock + 1000, (long) (*plen) >> 10);
     1566    mr_free(tmp);
     1567    paranoid_free(tempblock);
     1568    return (retval);
     1569}
     1570
     1571
     1572
     1573/**
     1574 * Add specified file/slice to the internal catalog of all archives written.
     1575 * This lets us restart on a new CD/tape/whatever if it runs out of room. We just
     1576 * write the last [buffer size] MB from the catalog to the new tape, so we know
     1577 * we have @e all archives on some CD/tape/whatever.
     1578 * @param type The type of file we're cataloging (afioball, slice, something else)
     1579 * @param number The fileset number or biggiefile number.
     1580 * @param aux The slice number if it's a biggiefile, or any other additional info.
     1581 * @param fn The original full pathname of the file we're recording.
     1582 * @return The index of the record we just added.
     1583 */
     1584int register_in_tape_catalog(t_archtype type, int number, long aux,
     1585                             char *fn)
     1586{
     1587    int last;
     1588    char fname[MAX_TAPECAT_FNAME_LEN+1];
     1589    char *p;
     1590
     1591    p = strrchr(fn, '/');
     1592    if (p) {
     1593        p++;
     1594    } else {
     1595        p = fn;
     1596    }
     1597    strncpy(fname, p, MAX_TAPECAT_FNAME_LEN);
     1598    fname[MAX_TAPECAT_FNAME_LEN] = '\0';
     1599    last = g_tapecatalog->entries;
     1600    if (last >= MAX_TAPECATALOG_ENTRIES) {
     1601        log_it
     1602            ("Warning - can't log #%d in tape catalog - too many entries already",
     1603             number);
     1604        return (-1);
     1605    }
     1606    g_tapecatalog->el[last].type = type;
     1607    g_tapecatalog->el[last].number = number;
     1608    g_tapecatalog->el[last].aux = aux;
     1609    g_tapecatalog->el[last].tape_posK = g_tape_posK;
     1610    strcpy(g_tapecatalog->el[last].fname, fname);
     1611    g_tapecatalog->entries++;
     1612    return (last);              // returns the index of the record we've jsut added
    14951613}
    14961614
     
    16001718
    16011719
    1602 /**
    1603  * Copy @p infile to the opened stream (CD or tape).
    1604  * @param bkpinfo The backup information structure. @c bkpinfo->media_size is the only field used.
    1605  * @param infile The file to write to the stream.
    1606  * @return 0 for success, nonzero for failure.
    1607  */
    1608 int write_file_to_stream_from_file(char *infile)
    1609 {
    1610     /*@ buffers **************************************************** */
    1611     char datablock[TAPE_BLOCK_SIZE];
    1612     char *checksum = NULL;
    1613     char *infile_basename;
    1614 
    1615     /*@ int ******************************************************** */
    1616     int retval = 0;
    1617     int noof_blocks;
    1618 
    1619     /*  unsigned int ch; */
    1620     unsigned int crc16;
    1621     unsigned int crctt;
    1622 
    1623     /*@ pointers *************************************************** */
    1624     FILE *fin;
    1625     char *p;
    1626 
    1627     /*@ long ******************************************************* */
    1628     long bytes_to_read = 0;
    1629     long i;
    1630 
    1631     off_t filesize;
    1632 
    1633 #ifdef EXTRA_TAPE_CHECKSUMS
    1634     int ch;
    1635 #endif
    1636 
    1637     /*@ initialize ************************************************ */
    1638     crc16 = 0;
    1639     crctt = 0;
    1640 
    1641 
    1642 
    1643     /*@ end vars *************************************************** */
    1644 
    1645     infile_basename = strrchr(infile, '/');
    1646     if (infile_basename) {
    1647         infile_basename++;
    1648     } else {
    1649         infile_basename = infile;
    1650     }
    1651     filesize = length_of_file(infile);
    1652     if (should_we_write_to_next_tape(bkpinfo->media_size, filesize)) {
    1653         start_to_write_to_next_tape();
    1654         write_backcatalog_to_tape();
    1655     }
    1656     p = strrchr(infile, '/');
    1657     if (!p) {
    1658         p = infile;
    1659     } else {
    1660         p++;
    1661     }
    1662     log_it("Writing file '%s' to tape (%ld KB)", p, (long) filesize >> 10);
    1663     write_header_block_to_stream(filesize, infile_basename, BLK_START_FILE);
    1664 //go_here_to_restart_saving_of_file:
    1665     if (!(fin = fopen(infile, "r"))) {
    1666         log_OS_error(infile);
    1667         return (1);
    1668     }
    1669     for (noof_blocks = 0; filesize > 0;
    1670          noof_blocks++, filesize -= bytes_to_read) {
    1671         if (filesize < TAPE_BLOCK_SIZE) {
    1672             bytes_to_read = (long) filesize;
    1673             for (i = 0; i < TAPE_BLOCK_SIZE; i++) {
    1674                 datablock[i] = '\0';
    1675             }
    1676         } else {
    1677             bytes_to_read = TAPE_BLOCK_SIZE;
    1678         }
    1679         if (fread(datablock, 1, (size_t) bytes_to_read, fin)) {
    1680             // FIXME
    1681         }
    1682         g_tape_posK +=
    1683             fwrite(datablock, 1, /*bytes_to_read */
    1684                    (size_t) TAPE_BLOCK_SIZE,
    1685                    g_tape_stream) / 1024;
    1686         if (g_sigpipe) {
    1687             log_it("Sigpipe occurred recently. I'll start a new tape.");
    1688             fclose(fin);
    1689             g_sigpipe = FALSE;
    1690             start_to_write_to_next_tape();
    1691             write_backcatalog_to_tape();    // kinda-sorta recursive :)
    1692             return (0);
    1693         }
    1694 #ifdef EXTRA_TAPE_CHECKSUMS
    1695         for (i = 0; i < bytes_to_read; i++) {
    1696             ch = datablock[i];
    1697             crc16 = updcrcr(crc16, (unsigned) ch);
    1698             crctt = updcrc(crctt, (unsigned) ch);
    1699         }
    1700 #endif
    1701     }
    1702     paranoid_fclose(fin);
    1703     mr_asprintf(checksum, "%04x%04x", crc16, crctt);
    1704     /* TODO: what does it do ??? */
    1705     write_header_block_to_stream((off_t)g_current_media_number, checksum, BLK_STOP_FILE);
    1706     mr_free(checksum);
    1707 
    1708 //  log_it("File '%s' written to tape.", infile);
    1709     return (retval);
    1710 }
    1711 
    1712 
    1713 
    1714 
    1715 
    1716 
    1717 
    1718 
    17191720
    17201721
Note: See TracChangeset for help on using the changeset viewer.