From: cbarratt Date: Sun, 30 Mar 2003 22:41:10 +0000 (+0000) Subject: - fixed directory browsing in BackupPC_Admin X-Git-Tag: v2_0_0beta2~7 X-Git-Url: http://git.rot13.org/?p=BackupPC.git;a=commitdiff_plain;h=c6cebe03e53dcc49f889cf15ccda5b0fe3acd235 - fixed directory browsing in BackupPC_Admin - fixed PoolWrite.pm to handle incorrect initial file sizes. If the file changes on the client after Rsync sends the file list, but before the deltas are sent, a different file size can get sent. - added binmode(STDIN) to BackupPC_tarExtract - added es.pm from Javier for Spanish translation. --- diff --git a/ChangeLog b/ChangeLog index 418ea8b..152b607 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,8 @@ now supports English and French, and adding more languages is now easy. New config paramater $Conf{Language} sets the language. +* Added Spanish translation es.pm from Javier. + * Added optional user-defined pre/post dump/restore commands, allowing things like database shutdown/startup for dumps. @@ -89,6 +91,11 @@ * Added catching of SIG_PIPE to BackupPC_dump, and changed catch_signal to ignore multiple signals of the same type. +* Added binmode(STDIN) to BackupPC_tarExtract, suggested by Pat LoPresti + to fix a problem a RedHat8 with perl 5.8.0. It's unclear why this + helps, but it should be benign. See: + http://sourceforge.net/mailarchive/forum.php?thread_id=1853018&forum_id=503 + * Added reporting of the largest number of hardlinks in the pool to the log file. diff --git a/bin/BackupPC_tarExtract b/bin/BackupPC_tarExtract index db5ec22..d8f6311 100755 --- a/bin/BackupPC_tarExtract +++ b/bin/BackupPC_tarExtract @@ -27,7 +27,7 @@ # #======================================================================== # -# Version 2.0.0_CVS, released 3 Feb 2003. +# Version 2.0.0beta0, released 23 Feb 2003. # # See http://backuppc.sourceforge.net. # @@ -374,6 +374,7 @@ sub processClose mkpath("$OutDir/$ShareName", 0, 0777); open(NEW_FILES, ">>", "$TopDir/pc/$host/NewFileList") || die("can't open $TopDir/pc/$host/NewFileList"); +binmode(STDIN); 1 while ( TarReadFile(*STDIN) ); 1 while ( sysread(STDIN, my $discard, 1024) ); diff --git a/cgi-bin/BackupPC_Admin b/cgi-bin/BackupPC_Admin index 5ad7c32..fc25b6e 100755 --- a/cgi-bin/BackupPC_Admin +++ b/cgi-bin/BackupPC_Admin @@ -39,7 +39,7 @@ # #======================================================================== # -# Version 2.0.0_CVS, released 3 Feb 2003. +# Version 2.0.0beta0, released 23 Feb 2003. # # See http://backuppc.sourceforge.net. # @@ -579,6 +579,7 @@ sub Action_Browse ErrorExit(eval("qq{$Lang->{Directory___EscHTML}}")); } } + $dir = "/$dir" if ( $dir !~ /^\// ); my $relDir = $dir; my $currDir = undef; @@ -605,12 +606,12 @@ sub Action_Browse my $fURI = $f; # URI escaped $f my $shareURI = $share; # URI escaped $share if ( $relDir eq "" ) { - $path = $f; + $path = "/$f"; } else { ($path = "$relDir/$f") =~ s{//+}{/}g; } if ( $shareURI eq "" ) { - $shareURI = $path; + $shareURI = $f; $path = "/"; } $path =~ s{^/+}{/}; @@ -719,12 +720,12 @@ EOF # Prune the last directory off $relDir, or at the very end # do the top-level directory. # - if ( $relDir eq "" || $relDir eq "/" ) { + if ( $relDir eq "" || $relDir eq "/" || $relDir !~ /(.*)\/(.*)/ ) { $currDir = $share; $share = ""; $relDir = ""; } else { - $relDir =~ s/(.*)\/(.*)/$1/; + $relDir = $1; $currDir = $2; } } diff --git a/conf/config.pl b/conf/config.pl index f0fe2b4..8b0e00c 100644 --- a/conf/config.pl +++ b/conf/config.pl @@ -429,7 +429,7 @@ $Conf{RestoreInfoKeepCnt} = 10; # $Conf{BackupFilesOnly} = { # 'c' => ['/myFiles', '/important'], # these are for 'c' share # 'd' => ['/moreFiles', '/archive'], # these are for 'd' share -# } +# }; # $Conf{BackupFilesOnly} = undef; @@ -1179,9 +1179,9 @@ $Conf{CgiURL} = undef; # # Language to use. See lib/BackupPC/Lang for the list of supported -# languages, which includes English (en) and French (fr). Currently -# this applies mainly to the CGI interface, but over time it might -# also include log files and other text output. +# languages, which include English (en), French (fr), and Spanish (es). +# Currently the Language setting applies to the CGI interface and email +# messages sent to users. Log files and other text is still in English. # $Conf{Language} = 'en'; diff --git a/doc-src/BackupPC.pod b/doc-src/BackupPC.pod index ab9ca1e..4b6e640 100644 --- a/doc-src/BackupPC.pod +++ b/doc-src/BackupPC.pod @@ -40,6 +40,11 @@ cancel backups and browse and restore files from backups. =item * +The http/cgi user interface has internationalization (i18n) support, +currently prodiving English, French and Spanish. + +=item * + No client-side software is needed. On WinXX the standard smb protocol is used to extract backup data. On linux or unix clients, rsync or tar (over ssh/rsh/nfs) is used to extract backup data. @@ -421,7 +426,7 @@ Rsync as a transport method. If you are using smb to backup WinXX machines you need smbclient and nmblookup from the samba package. You will also need nmblookup if you are backing up linux/unix DHCP machines. See L. -Version >= 2.2.0 of Samba is required (smbclient's tar feature in +Version 2.2.0 or later of Samba is required (smbclient's tar feature in 2.0.8 and prior has bugs for file path lengths around 100 characters and generates bad output when file lengths change during the backup). @@ -446,7 +451,7 @@ Use "rsync --version" to check your version. For BackupPC to use Rsync you will also need to install the perl File::RsyncP module, which is available from -L. Version 0.31 is required. +L. Version 0.31 or later is required. =item * @@ -526,7 +531,7 @@ You can run "perldoc Archive::Zip" to see if this module is installed. To use rsync and rsyncd with BackupPC you will need to install File::RsyncP. You can run "perldoc File::RsyncP" to see if this module is installed. File::RsyncP is available from L. -Version 0.20 is required. +Version 0.31 or later is required. =back @@ -685,7 +690,7 @@ This is typically the host name or NetBios name of the client machine and should be in lower case. The host name can contain spaces (escape with a backslash), but it is not recommended. -Please read the second L. +Please read the section L. In certain cases you might want several distinct clients to refer to the same physical machine. For example, you might have a database @@ -702,7 +707,7 @@ real host name of the machine. Starting with v2.0.0 the way hosts are discovered has changed and now in most cases you should specify 0 for the DHCP flag, even if the host has a dynamically assigned IP address. -Please read the second L +Please read the section L to understand whether you need to set the DHCP flag. You only need to set DHCP to 1 if your client machine doesn't @@ -895,6 +900,10 @@ of SSH you have by typing "ssh" or "man ssh".) =item OpenSSH Instructions +Depending upon your OpenSSH installation, many of these steps can be +replaced by running the scripts ssh-user-config and ssh-host-config +included with OpenSSH. You still need to manually exchange the keys. + =over 4 =item Key generation @@ -1248,6 +1257,7 @@ to Apache's httpd.conf file: SetHandler perl-script PerlHandler Apache::Registry Options ExecCGI + PerlSendHeader On @@ -1813,7 +1823,7 @@ is always done to verify if two files are really the same. Identical files on multiples backups are represented by hard links. Hardlinks are used so that identical files all refer to the same physical file on the server's disk. Also, hard links maintain -reference counts so that BackupPC knows when to deleted unused files +reference counts so that BackupPC knows when to delete unused files from the pool. For the computer-science majors among you, you can think of the pooling @@ -2882,6 +2892,8 @@ Copyright (C) 2001-2003 Craig Barratt Xavier Nicollet, with additions from Guillaume Filion, added the internationalization (i18n) support to the CGI interface for v2.0.0. +Xavier provided the French translation fr.pm, with additions from +Guillaume. Ryan Kucera contributed the directory navigation code and images for v1.5.0. He also contributed the first skeleton of BackupPC_restore. @@ -2889,6 +2901,8 @@ for v1.5.0. He also contributed the first skeleton of BackupPC_restore. Guillaume Filion wrote BackupPC_zipCreate and added the CGI support for zip download, in addition to some CGI cleanup, for v1.5.0. +Javier provided the Spanish translation, es.pm. + Many people have reported bugs, made useful suggestions and helped with testing; see the ChangeLog and the mail lists. diff --git a/lib/BackupPC/Lang/es.pm b/lib/BackupPC/Lang/es.pm new file mode 100644 index 0000000..caa3f75 --- /dev/null +++ b/lib/BackupPC/Lang/es.pm @@ -0,0 +1,1006 @@ +#!/bin/perl -T + +#my %lang; + +#use strict; + +# -------------------------------- + +$Lang{Start_Full_Backup} = "Comenzar copia de seguridad completa"; +$Lang{Start_Incr_Backup} = "Comenzar copia de seguridad incremental"; +$Lang{Stop_Dequeue_Backup} = "Parar/anular copia de seguridad"; +$Lang{Restore} = "Restaurar"; + +# ----- + +$Lang{H_BackupPC_Server_Status} = "Estado del Servidor BackupPC"; + +$Lang{BackupPC_Server_Status}= < +\${h2(\"Información General del servidor\")} + +
    +
  • El PID del servidor es \$Info{pid}, en el host \$Conf{ServerHost}, + version \$Info{Version}, iniciado el \$serverStartTime. +
  • Esta información de estado se ha generado el \$now. +
  • La cola de PC´s se activará de nuevo el \$nextWakeupTime. +
  • Información adicional: +
      +
    • \$numBgQueue solicitudes pendientes de copia de seguridad desde la última activación programada, +
    • \$numUserQueue solicitudes pendientes de copia de seguridad de usuarios, +
    • \$numCmdQueue solicitudes de comandos pendientes , + \$poolInfo +
    • El sistema de archivos estaba recientemente al \$Info{DUlastValue}% + (\$DUlastTime), el máximo de hoy es \$Info{DUDailyMax}% (\$DUmaxTime) + y el máximo de ayer era \$Info{DUDailyMaxPrev}%. +
    +
+ +\${h2("Trabajos en Ejecución")} +

+ + + + + + + + + \$tarPidHdr +\$jobStr +
Host Tipo Usuario Hora de Inicio Comando PID Transfer. PID
+

+ +\${h2("Fallos que Precisan Atención")} +

+ + + + + + + + +\$statusStr +
Host Tipo Usuario Ultimo Intento Detalles Hora del error Ultimo error (ping no incluido)
+EOF + +# -------------------------------- +$Lang{BackupPC__Server_Summary} = "BackupPC: Resumen del Servidor"; +$Lang{BackupPC_Summary}=< +Este status ha sido generado el \$now. +

+ +\${h2("Hosts con Buenas Copias de Seguridad")} +

+Il y a \$hostCntGood hosts tienen copia de seguridad, de un total de : +

    +
  • \$fullTot copias de seguridad completas con tamaño total de \${fullSizeTot} GB + (antes de agrupar y comprimir), +
  • \$incrTot copias de seguridad incrementales con tamaño total de \${incrSizeTot} GB + (antes de agrupar y comprimir). +
+ + + + + + + + + + + +\$strGood +
Host Usuario #Completo Completo Antig./Días Completo Tamaño/GB Velocidad MB/sec #Incrementales Incrementales Antig/Días Estado Ultimo Intento
+

+ +\${h2("Hosts Sin Copias de Seguridad")} +

+Hay \$hostCntNone hosts sin copias de seguridad. +

+ + + + + + + + + + + +\$strNone +
Host Usuario #Completo Completo Antig./Días Completo Tamaño/GB Velocidad MB/sec #Incrementales Incrementales Antig/Días Estado Ultimo Intento
+EOF + +# ----------------------------------- +$Lang{Pool_Stat} = <El grupo tiene \${poolSize}GB incluyendo \$info->{"\${name}FileCnt"} archivos + y \$info->{"\${name}DirCnt"} directorios (as of \$poolTime), +

  • El procesamiento del grupo da \$info->{"\${name}FileCntRep"} archivos + repetidos cuya cadena más larga es \$info->{"\${name}FileRepMax"}, +
  • El proceso de limpieza nocturna ha eliminado \$info->{"\${name}FileCntRm"} archivos de + tamaño \${poolRmSize}GB (around \$poolTime), +EOF + +# -------------------------------- +$Lang{BackupPC__Backup_Requested_on__host} = "BackupPC: Copia de Seguridad Solicitada en \$host"; +# -------------------------------- +$Lang{REPLY_FROM_SERVER} = < +La respuesta del servidor fué: \$reply +

    +Volver a \$host home page. +EOF +# -------------------------------- +$Lang{BackupPC__Start_Backup_Confirm_on__host} = "BackupPC: Confirme inicio de copia de seguridad en \$host"; +# -------------------------------- +$Lang{Are_you_sure_start} = < +Va a hacer comenzar una copia de seguridad \$type en \$host. + +

    + + + +¿Realmente quiere hacer esto? + + +
    +EOF +# -------------------------------- +$Lang{BackupPC__Stop_Backup_Confirm_on__host} = "BackupPC: Confirmación de Parada de Copia de Seguridad en \$host"; +# -------------------------------- +$Lang{Are_you_sure_stop} = < +Está a punto de parar/quitar de la cola las copias de seguridad en \$host; + +
    + + +Asimismo, por favor no empiece otra copia de seguridad durante + horas. +

    +¿Realmente quiere hacer esto? + + +

    + +EOF +# -------------------------------- +$Lang{Only_privileged_users_can_view_queues_} = "Sólo los administradores pueden ver las colas."; +# -------------------------------- +$Lang{BackupPC__Queue_Summary} = "BackupPC: Resumen de la Cola"; +# -------------------------------- +$Lang{Backup_Queue_Summary} = < +\${h2("Resumen de la Cola de Usuarios")} +

    +Las siguientes solicitudes de usuarios están actualmente en cola: + + + + +\$strUser +
    Host Hora Sol. Usuario
    +

    + +\${h2("Resumen de Cola en Segundo Plano")} +

    +Las siguientes solicitudes en segundo plano están actualmente en cola: + + + + +\$strBg +
    Host Hora Sol. Usuario
    +

    + +\${h2("Resumen de Cola de Comandos")} +

    +Los siguientes comandos están actualmente en cola: + + + + + +\$strCmd +
    Host Hora Sol. Usuario Comando
    +EOF + +# -------------------------------- +$Lang{Backup_PC__Log_File__file} = "BackupPC: Archivo de Registro \$file"; +$Lang{Log_File__file__comment} = < +EOF +# -------------------------------- +$Lang{Contents_of_log_file} = <\$file, modificado \$mtimeStr \$comment +EOF + +# -------------------------------- +$Lang{skipped__skipped_lines} = "[ saltadas \$skipped lineas ]\n"; +# -------------------------------- +$Lang{_pre___Can_t_open_log_file__file} = "

    \nNo puedo abrir el archivo de registro \$file\n";
    +
    +# --------------------------------
    +$Lang{BackupPC__Log_File_History} = "BackupPC: Historial de Archivo de Registro";
    +$Lang{Log_File_History__hdr} = <
    +
    +
    +    
    +    
    +\$str
    +
    File Size Hora Modificación
    +EOF + +# ------------------------------- +$Lang{Recent_Email_Summary} = < + + + + + +\$str +
    Destinatario Host Hora Asunto
    +EOF + + +# ------------------------------ +$Lang{Browse_backup__num_for__host} = "BackupPC: Hojear copia de seguridad \$num de \$host"; + +# ------------------------------ +$Lang{Restore_Options_for__host} = "BackupPC: Opciones de restauración para \$host"; +$Lang{Restore_Options_for__host2} = < +Ha seleccionado los siguientes archivos/directorios de +la unidad \$share, copia número #\$num: +
      +\$fileListStr +
    +

    +Tiene tres opciones para restaurar estos archivos/directorios. +Por favor, seleccione una de las siguientes opciones. +

    +\${h2("Opción 1: Restauración Directa")} +

    +Puede empezar un proceso que restaurará estos archivos directamente en +\$host. +

    +¡Atención!: ¡Cualquier archivo existente con el mismo nombre que los que ha +seleccionado será sobreescrito! + +

    + + + +\$hiddenStr + + + + + + + + + + + + + +
    Restaurar los archivos al host
    Restaurar los archivos a la unidad
    Restaurar los archivos bajo el directorio
    (relativo a la unidad)
    +
    +EOF + +# ------------------------------ +$Lang{Option_2__Download_Zip_archive} = < +Puede descargar un archivo comprimido (.zip) conteniendo todos los archivos y directorios que +ha seleccionado. Después puede hacer uso de una aplicación local, como WinZip, +para ver o extraer cualquiera de los archivos. +

    +¡Atención!: Dependiendo de que archivos/carpetas haya seleccionado, +este archivo puede ser muy grande. Podría tardar muchos minutos +crear y transferir el archivo. Además necesitará suficiente espacio el el disco +local para almacenarlo. +

    +

    + + + +\$hiddenStr + + Hacer archivo relativo +a \${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)} +(en caso contrario el archivo contendrá las rutas completas). +
    +Compresión (0=desactivada, 1=rápida,...,9=máxima) + +
    + +
    +EOF + +# ------------------------------ + +$Lang{Option_2__Download_Zip_archive2} = < +El programa Archive::Zip no está instalado, de modo que no podrá descargar un +archivo comprimido zip. +Por favor, solicite a su administrador de sistemas que instale Archive::Zip de +www.cpan.org. +

    +EOF + + +# ------------------------------ +$Lang{Option_3__Download_Zip_archive} = < +Puede descargar un archivo comprimido (.Tar) conteniendo todos los archivos y +directorios que ha seleccionado. Después puede hacer uso de una aplicación +local, como Tar o WinZip,para ver o extraer cualquiera de los archivos. +

    +¡Atención!: Dependiendo de que archivos/carpetas haya seleccionado, +este archivo puede ser muy grande. Podría tardar muchos minutos +crear y transferir el archivo. Además necesitará suficiente espacio el el disco +local para almacenarlo. +

    +

    + + + +\$hiddenStr + + Hacer el archivo +relativo a \${EscHTML(\$pathHdr eq "" ? "/" : \$pathHdr)} +(en caso contrario el archivo contendrá las rutas completas). +
    + +
    +EOF + + +# ------------------------------ +$Lang{Restore_Confirm_on__host} = "BackupPC: Restore Confirm on \$host"; + +$Lang{Are_you_sure} = < +Está a punto de comenzar una restauración directamente a la máquina \$In{hostDest}. +Los siguientes archivos serán restaurados en la unidad \$In{shareDest}, de +la copia de seguridad número \$num: +

    + + +\$fileListStr +
    Archivo/Dir Original Será restaurado a
    + +

    + + + + + + +\$hiddenStr +Do you really want to do this? + + +
    +EOF + + +# -------------------------- +$Lang{Restore_Requested_on__hostDest} = "BackupPC: Restauración solicitada en \$hostDest"; +$Lang{Reply_from_server_was___reply} = < +La respuesta del servidor fué: \$reply +

    +Go back to \$hostDest home page. +EOF + +# ------------------------- +$Lang{Host__host_Backup_Summary} = "BackupPC: Host \$host Resumen de Copia de Seguridad"; + +$Lang{Host__host_Backup_Summary2} = < +\$warnStr +

      +\$statusStr +
    + +\${h2("Acciones del Usuario")} +

    +

    + +\$startIncrStr + + +
    + +\${h2("Resumen de Copia de Seguridad")} +

    +Haga click en el número de copia de seguridad para revisar y restaurar archivos. + + + + + + + + + +\$str +
    Copia Nº Tipo Completo Fecha Inicio Duracion/mn Antigüedad/dias Ruta a la Copia en el Servidor
    +

    + +\$restoreStr + +\${h2("Resumen de Errores de Transferencia")} +

    + + + + + + + + + +\$errStr +
    Copia Nº Tipo Ver Nº Xfer errs Nº err. archivos Nº err. unidades Nº err. tar
    +

    + +\${h2("Resumen de Total/Tamaño de Archivos Reutilizados")} +

    +Los archivos existentes son aquellos que ya están en el lote; los nuevos son +aquellos que se han añadido al lote. +Los archivos vacíos y los errores SMB no cuentan en las cifras de reutilizados +ni en la de nuevos. + + + + + + + + + + + + + + + + + +\$sizeStr +
    Totales Archivos Existentes Archivos Nuevos
    Copia Nº Tipo Nº Archivos Tamaño/MB MB/sg Nº Archivos Tamaño/MB Nº Archivos Tamaño/MB
    +

    + +\${h2("Resumen de Compresión")} +

    +Efectividad de compresión para los archivos ya existentes en el lote y los +archivos nuevos comprimidos. + + + + + + + + + + + + + + + +\$compStr +
    Archivos Existentes Archivos Nuevos
    Copia Nº Tipo Nivel Comp Tamaño/MB Comp/MB Comp Tamaño/MB Comp/MB Comp
    +

    +EOF + +# ------------------------- +$Lang{Error} = "BackupPC: Error"; +$Lang{Error____head} = <\$mesg

    +EOF + +# ------------------------- +$Lang{NavSectionTitle_} = "Servidor"; + +# ------------------------- +$Lang{Backup_browse_for__host} = < + + + +
      +
    • Está revisando la copia de seguridad Nº\$num, que comenzó hacia las \$backupTime + (hace \$backupAge dias), +\$filledBackup +
    • Haga click en uno de los directorios de abajo para revisar sus contenidos, +
    • Haga click en un archivo para restaurarlo. +
    + +\${h2("Contenido de \${EscHTML(\$dirDisplay)}")} +
    + + + + + +
    + +
    + +
    + \$dirStr +
    +
    + + +
    +
    + + \$fileHeader + \$topCheckAll + \$fileStr + \$checkAll +
    +
    +
    + +
    +
    +EOF + +# ------------------------------ +$Lang{Restore___num_details_for__host} = "BackupPC: Detalles de la restauración Nº\$num de \$host"; + +$Lang{Restore___num_details_for__host2 } = < + + + + + + + + + + + + + + + + + + + +
    Número \$Restores[\$i]{num}
    Solicitado por \$RestoreReq{user}
    Hora Petición \$reqTime
    Resultado \$Restores[\$i]{result}
    Mensaje de Error \$Restores[\$i]{errorMsg}
    Host Origen \$RestoreReq{hostSrc}
    Nº copia origen \$RestoreReq{num}
    Unidad origen \$RestoreReq{shareSrc}
    Host destino \$RestoreReq{hostDest}
    Unidad destino \$RestoreReq{shareDest}
    Hora comienzo \$startTime
    Duración \$duration min
    Número de archivos \$Restores[\$i]{nFiles}
    Tamaño total \${MB} MB
    Tasa de transferencia \$MBperSec MB/sec
    Errores creación Tar \$Restores[\$i]{tarCreateErrs}
    Errores de transferencia \$Restores[\$i]{xferErrs}
    Archivo registro de transferencia +View, +Errors +
    +

    +\${h1("Lista de Archivos/Directorios")} +

    + + +\$fileListStr +
    Dir/archivo originalRestaurado a
    +EOF + +# ----------------------------------- +$Lang{Email_Summary} = "BackupPC: Resumen de Correos"; + +# ----------------------------------- +# !! ERROR messages !! +# ----------------------------------- +$Lang{BackupPC__Lib__new_failed__check_apache_error_log} = "BackupPC::Lib->nuevo ha fallado: revise el error_log de apache\n"; +$Lang{Wrong_user__my_userid_is___} = + "Usuario erróneo: mi userid es \$>, en lugar de \$uid" + . "(\$Conf{BackupPCUser})\n"; +$Lang{Only_privileged_users_can_view_PC_summaries} = "Sólo los usuarios autorizados pueden ver los resúmenes de PC´s."; +$Lang{Only_privileged_users_can_stop_or_start_backups} = + "Sólo los usuarios autorizados pueden comenzar a detener las copias" + . " \${EscHTML(\$host)}."; +$Lang{Invalid_number__num} = "Número no válido \$num"; +$Lang{Unable_to_open__file__configuration_problem} = "No puedo abrir \$file: ¿problema de configuración?"; +$Lang{Only_privileged_users_can_view_log_or_config_files} = "Sólo los usuarios autorizados pueden ver registros o archivos de configuración."; +$Lang{Only_privileged_users_can_view_log_files} = "Sólo los usuarios autorizados pueden ver archivos de registro."; +$Lang{Only_privileged_users_can_view_email_summaries} = "Sólo los usuarios autorizados pueden ver resúmenes de correo."; +$Lang{Only_privileged_users_can_browse_backup_files} = "Sólo los usuarios autorizados pueden revisar los archivos de las copias de seguridad" + . " for host \${EscHTML(\$In{host})}."; +$Lang{Empty_host_name} = "Número de host vacío."; +$Lang{Directory___EscHTML} = "El directorio \${EscHTML(\"\$TopDir/pc/\$host/\$num\")}" + . " está vacío"; +$Lang{Can_t_browse_bad_directory_name2} = "No puedo mostrar un nombre de directorio erróneo" + . " \${EscHTML(\$relDir)}"; +$Lang{Only_privileged_users_can_restore_backup_files} = "Sólo los usuarios autorizados pueden restaurar copias de seguridad" + . " para el host \${EscHTML(\$In{host})}."; +$Lang{Bad_host_name} = "Nombre de host erróneo \${EscHTML(\$host)}"; +$Lang{You_haven_t_selected_any_files__please_go_Back_to} = "No ha seleccionado nigún archivo; por favor, vuelva a" + . " seleccione algunos archivos."; +$Lang{Nice_try__but_you_can_t_put} = "Buen intento, pero no puede usar \'..\' en los nombres de archivo"; +$Lang{Host__doesn_t_exist} = "El Host \${EscHTML(\$In{hostDest})} no existe"; +$Lang{You_don_t_have_permission_to_restore_onto_host} = "No tiene autorización para restaurar en el host" + . " \${EscHTML(\$In{hostDest})}"; +$Lang{Can_t_open_create} = "No puedo abrir/crear " + . "\${EscHTML(\"\$TopDir/pc/\$hostDest/\$reqFileName\")}"; +$Lang{Only_privileged_users_can_restore_backup_files2} = "Sólo los usuarios autorizados pueden restaurar copias de seguridad" + . " del host \${EscHTML(\$host)}."; +$Lang{Empty_host_name} = "Nombre de host vacío"; +$Lang{Unknown_host_or_user} = "Unknown host or user \${EscHTML(\$host)}"; +$Lang{Only_privileged_users_can_view_information_about} = "Sólo los usuarios autorizados pueden ver información del" + . " host \${EscHTML(\$host)}." ; +$Lang{Only_privileged_users_can_view_restore_information} = "Sólo los usuarios autorizados pueden ver información de restauración."; +$Lang{Restore_number__num_for_host__does_not_exist} = "El número de restauración \$num del host \${EscHTML(\$host)} " + . " no existe."; + +$Lang{Unable_to_connect_to_BackupPC_server} = "Imposible conectar al servidor BackupPC", + "Este script CGI (\$MyURL) no puede conectar al servidor BackupPC" + . " en \$Conf{ServerHost} puerto \$Conf{ServerPort}. El error" + . " fué: \$err.", + "Quizá el servidor BackupPC no está activo o hay un " + . " error de configuración. Por favor informe a su administrador de sistemas."; + +$Lang{Can_t_find_IP_address_for} = "No puedo encontrar la dirección IP de \${EscHTML(\$host)}"; +$Lang{host_is_a_DHCP_host} = < +Hasta que vea \$host en una dirección DHCP concreta, sólo puede +comenzar este proceso desde la propia máquina cliente. +EOF + +######################## +# ok you can do it then +######################## + +$Lang{Backup_requested_on_DHCP__host} = "Copia de seguridad solicitada en DHCP \$host (\$In{hostIP}) por" + . " \$User desde \$ENV{REMOTE_ADDR}"; + +$Lang{Backup_requested_on__host_by__User} = "Copia de seguridad solicitada en \$host por \$User"; +$Lang{Backup_stopped_dequeued_on__host_by__User} = "Copia de seguridad detenida/desprogramada en \$host por \$User"; +$Lang{log_User__User_downloaded_tar_archive_for__host} = "El usuario del registro \$User ha descargado un archivo Tar para \$host," + . " copia de seguridad \$num; los archivos eran: " + . " \${join(\", \", \@fileListTrim)}"; + +$Lang{log_User__User_downloaded_zip_archive_for__host}= "El usuario del registro \$User ha descargado un archivo Zip para \$host," + . " copia de seguridad \$num; los archivos eran: " + . "\${join(\", \", \@fileListTrim)}"; + +$Lang{Restore_requested_to_host__hostDest__backup___num} = "Restauración solicitada para el host \$hostDest, copia de seguridad #\$num," + . " por \$User desde \$ENV{REMOTE_ADDR}"; + +# ------------------------------------------------- +# ------- Stuff that was forgotten ---------------- +# ------------------------------------------------- + +$Lang{Status} = "Estado"; +$Lang{PC_Summary} = "Resumen PC"; +$Lang{LOG_file} = "Archivo Registro"; +$Lang{Old_LOGs} = "Registros antiguos"; +$Lang{Email_summary} = "Resumen correo"; +$Lang{Config_file} = "Archivo configuración"; +$Lang{Hosts_file} = "Archivo Hosts"; +$Lang{Current_queues} = "Colas actuales"; +$Lang{Documentation} = "Documentación"; + +$Lang{Host_or_User_name} = "Host o usuario:"; +$Lang{Go} = "Aceptar"; +$Lang{Hosts} = "Hosts"; + +$Lang{This_PC_has_never_been_backed_up} = "

    !Nunca se ha hecho copia de seguridad de este PC!

    \n"; +$Lang{This_PC_is_used_by} = "
  • This PC es utilizado por \${UserLink(\$user)}"; + +# ------------ +$Lang{Last_email_sent_to__was_at___subject} = <El último mensaje enviado a \${UserLink(\$user)} fué a las \$mailTime, asunto "\$subj". +EOF +# ------------ +$Lang{The_command_cmd_is_currently_running_for_started} = <El comando \$cmd está ejecutandose para \$host, comenzado a \$startTime. +EOF + +# ----------- +$Lang{Host_host_is_queued_on_the_background_queue_will_be_backed_up_soon} = <El host \$host está en cola en la cola en segundo plano (pronto tendrá copia de seguridad). +EOF + +# ---------- +$Lang{Host_host_is_queued_on_the_user_queue__will_be_backed_up_soon} = <Host \$host está en cola en la cola de usuarios (pronto tendrá copia de seguridad). +EOF + +# --------- +$Lang{A_command_for_host_is_on_the_command_queue_will_run_soon} = <Un comando para \$host está en la cola de comandos (se ejecutará pronto). +EOF + +# -------- +$Lang{Last_status_is_state_StatusHost_state_reason_as_of_startTime} = <El último estado fué \"\$Lang->{\$StatusHost{state}}\"\$reason a las \$startTime. +EOF + +# -------- +$Lang{Last_error_is____EscHTML_StatusHost_error} = <El último error fué \"\${EscHTML(\$StatusHost{error})}\" +EOF + +# ------ +$Lang{Pings_to_host_have_failed_StatusHost_deadCnt__consecutive_times} = <Los pings a \$host han fallado \$StatusHost{deadCnt} veces consecutivas. +EOF + +# ----- +$Lang{Prior_to_that__pings} = "Antes de eso, pings"; + +# ----- +$Lang{priorStr_to_host_have_succeeded_StatusHostaliveCnt_consecutive_times} = <\$priorStr a \$host han tenido éxito \$StatusHost{aliveCnt} + veces consecutivas. +EOF + +$Lang{Because__host_has_been_on_the_network_at_least__Conf_BlackoutGoodCnt_consecutive_times___} = <Dado que \$host ha estado en la red al menos \$Conf{BlackoutGoodCnt} +veces consecutivas, no se le realizará copia de seguridad desde \$t0 hasta \$t1 en \$days. +EOF + +$Lang{Backups_are_deferred_for_hours_hours_change_this_number} = <Las copias de seguridad se retrasarán durante \$hours hours +(Cambie este número). +EOF + +$Lang{tryIP} = " y \$StatusHost{dhcpHostIP}"; + +$Lang{Host_Inhost} = "Host \$In{host}"; + +$Lang{checkAll} = < + Seleccionar todo + + + +EOF + +$Lang{fileHeader} = < Nombre + Tipo + Modo + Nº + Tamaño + Hora Mod. + +EOF + +$Lang{Home} = "Principal"; +$Lang{Last_bad_XferLOG} = "Ultimo error en registro de transferencia"; +$Lang{Last_bad_XferLOG_errors_only} = "Ultimo error en registro de transferencia (errores sólo)"; + +$Lang{This_display_is_merged_with_backup} = < Esta pantalla está unida a la copia de seguridad Nº\$numF. +EOF + +$Lang{Visit_this_directory_in_backup} = < Explorar este directorio en copia de seguridad Nº\$otherDirs. +EOF + +$Lang{Restore_Summary} = < +Haga click en el número de restauración para ver sus detalles. + + + + + + + + + + +\$restoreStr +
    Restauración Nº Resultado Fecha Inicio Dur/mins Nº Archivos MB Nº Err. Tar Nº Err. Transf.#xferErrs
    +

    +EOF + +$Lang{BackupPC__Documentation} = "BackupPC: Documentacion"; + +$Lang{No} = "no"; +$Lang{Yes} = "si"; + +$Lang{The_directory_is_empty} = <El directorio \${EscHTML(\$dirDisplay)} está vacio + +EOF + +#$Lang{on} = "activo"; +$Lang{off} = "inactivo"; + +$Lang{full} = "completo"; +$Lang{incremental} = "incremental"; + +$Lang{failed} = "fallido"; +$Lang{success} = "éxito"; +$Lang{and} = "y"; + +# ------ +# Hosts states and reasons +$Lang{Status_idle} = "inactivo"; +$Lang{Status_backup_starting} = "comenzando copia de seguridad"; +$Lang{Status_backup_in_progress} = "copia de seguridad ejecutándose"; +$Lang{Status_restore_starting} = "comenzando restauración"; +$Lang{Status_restore_in_progress} = "restauración ejecutándose"; +$Lang{Status_link_pending} = "conexión pendiente"; +$Lang{Status_link_running} = "conexión en curso"; + +$Lang{Reason_backup_done} = "copia de seguridad realizada"; +$Lang{Reason_restore_done} = "restauración realizada"; +$Lang{Reason_nothing_to_do} = "nada por hacer"; +$Lang{Reason_backup_failed} = "copia de seguridad fallida"; +$Lang{Reason_no_ping} = "no hay ping"; +$Lang{Reason_backup_canceled_by_user} = "copia cancelada por el usuario"; + +# --------- +# Email messages + +# No backup ever +$Lang{EMailNoBackupEverSubj} = "BackupPC: ningúna copia de \$host ha tenido éxito"; +$Lang{EMailNoBackupEverMesg} = <<'EOF'; +To: $user$domain +cc: +Subject: $subj + +Estimado $userName, + +Su PC ($host) nunca ha completado una copia de seguridad mediante nuestro +programa de copias de seguridad. Las copias de seguridad deberían ejecutarse +automáticamente cuando su PC se conecta a la red. Debería contactar con su +soporte técnico si: + + - Su ordenador ha estado conectado a la red con regularidad. Esto implicaría + que existe algún problema de instalación o configuración que impide que se + realicen las copias de seguridad. + + - No desea realizar copias de seguridad y no quiere recibir más mensajes + como éste. + +De no ser así, asegúrese de que su PC está conectado a la red la próxima vez +que esté en la oficina. + +Saludos: +Agente BackupPC +http://backuppc.sourceforge.net +EOF + +# No recent backup +$Lang{EMailNoBackupRecentSubj} = "BackupPC: no hay copias de seguridad recientes de \$host"; +$Lang{EMailNoBackupRecentMesg} = <<'EOF'; +To: $user$domain +cc: +Subject: $subj + +Estimado $userName, + +No se ha podido completar ninguna copia de seguridad de su PC ($host) durante +$days días. +Su PC ha realizado copias de seguridad correctas $numBackups veces desde +$firstTime hasta hace $days días. +Las copias de seguridad deberían efectuarse automáticamente cuando su PC está +conectado a la red. + +Si su PC ha estado conectado durante algunas horas a la red durante los últimos +$days días debería contactar con su soporte técnico para ver porqué las copias +de seguridad no funcionan adecuadamente. + +Por otro lado, si está fuera de la oficina, no hay mucho que se pueda hacer al +respecto salvo copiar manualmente los archivos especialmente críticos a otro +soporte físico. Debería estar al corriente de que cualquier archivo que haya +creado o modificado en los últimos $days días (incluyendo todo el correo nuevo +y archivos adjuntos) no pueden ser restaurados si su disco se avería. + +Saludos: +Agente BackupPC +http://backuppc.sourceforge.net +EOF + +# Old Outlook files +$Lang{EMailOutlookBackupSubj} = "BackupPC: Los archivos de Outlook de \$host necesitan ser copiados"; +$Lang{EMailOutlookBackupMesg} = <<'EOF'; +To: $user$domain +cc: +Subject: $subj + +Estimado $userName, + +Los archivos de Outlook de su PC tienen $howLong. +Estos archivos contienen todo su correo, adjuntos, contactos e información de +su agenda. Su PC ha sido correctamente salvaguardado $numBackups veces desde +$firstTime hasta hace $lastTime días. Sin embargo, Outlook bloquea todos sus +archivos mientras funciona, impidiendo que pueda hacerse copia de seguridad de +los mismos. + +Se le recomienda hacer copia de seguridad de los archivos de Outlook cuando esté +conectado a la red cerrando Outlook y el resto de aplicaciones y utilizando su +navegador de internet. Haga click en este vínculo: + + $CgiURL?host=$host + +Seleccione "Comenzar copia de seguridad incremental" dos veces para comenzar +una neva copia de seguridad incremental. +Puede seleccionar "Volver a la página de $host " y hacer click en "refrescar" +para ver el estado del proceso de copia de seguridad. Debería llevarle sólo +unos minutos completar el proceso. + +Saludos: +Agente BackupPC +http://backuppc.sourceforge.net +EOF + +$Lang{howLong_not_been_backed_up} = "no se le ha realizado una copia de seguridad con éxito"; +$Lang{howLong_not_been_backed_up_for_days_days} = "no se le ha realizado una copia de seguridad durante \$days días"; + +#end of lang_en.pm diff --git a/lib/BackupPC/PoolWrite.pm b/lib/BackupPC/PoolWrite.pm index fde4f5d..8ec9fd2 100644 --- a/lib/BackupPC/PoolWrite.pm +++ b/lib/BackupPC/PoolWrite.pm @@ -56,7 +56,7 @@ # #======================================================================== # -# Version 2.0.0_CVS, released 3 Feb 2003. +# Version 2.0.0beta0, released 23 Feb 2003. # # See http://backuppc.sourceforge.net. # @@ -108,11 +108,27 @@ sub write return if ( $a->{eof} ); $a->{data} .= $$dataRef if ( defined($dataRef) ); return if ( length($a->{data}) < $BufSize && defined($dataRef) ); - if ( !defined($a->{digest}) && $a->{fileSize} > 0 ) { + + # + # Correct the fileSize if it is wrong (rsync might transfer + # a file whose length is different to the length sent with the + # file list if the file changes between the file list sending + # and the file sending). Here we only catch the case where + # we haven't computed the digest (ie: we have written no more + # than $BufSize. We catch the big file case below. + # + if ( !defined($dataRef) && !defined($a->{digest}) + && $a->{fileSize} != length($a->{data}) ) { + $a->{fileSize} = length($a->{data}); + } + + if ( !defined($a->{digest}) && length($a->{data}) > 0 ) { # # build a list of all the candidate matching files # my $md5 = Digest::MD5->new; + $a->{fileSize} = length($a->{data}) + if ( $a->{fileSize} < length($a->{data}) ); $a->{digest} = $a->{bpc}->Buffer2MD5($md5, $a->{fileSize}, \$a->{data}); if ( !defined($a->{base} = $a->{bpc}->MD52Path($a->{digest}, $a->{compress})) ) { @@ -151,7 +167,7 @@ sub write } } my $dataLen = length($a->{data}); - if ( !defined($a->{fhOut}) && $a->{fileSize} > 0 ) { + if ( !defined($a->{fhOut}) && length($a->{data}) > 0 ) { # # See if the new chunk of data continues to match the # candidate files. @@ -257,6 +273,74 @@ sub write foreach my $f ( @{$a->{files}} ) { $f->{fh}->close(); } + + # + # Make sure the fileSize was correct. See above for comments about + # rsync. + # + if ( $a->{nWrite} != $a->{fileSize} ) { + # + # Oops, fileSize was wrong, so our MD5 digest was wrong and our + # effort to match files likely failed. This is ugly, but our + # only choice at this point is to re-write the entire file with + # the correct length. We need to rename the file, open it for + # reading, and then re-write the file with the correct length. + # + + #print("Doing big file fixup ($a->{fileSize} != $a->{nWrite})\n"); + + my($fh, $fileName); + $a->{fileSize} = $a->{nWrite}; + if ( $a->{fileName} =~ /(.*)\// ) { + $fileName = $1; + } else { + $fileName = "."; + } + + # + # Find a unique target temporary file name + # + my $i = 0; + while ( -f "$fileName/t$$.$i" ) { + $i++; + } + $fileName = "$fileName/t$$.$i"; + $a->{fhOut}->close(); + if ( !rename($a->{fileName}, $fileName) + || !defined($fh = BackupPC::FileZIO->open($fileName, 0, + $a->{compress})) ) { + push(@{$a->{errors}}, "Can't rename $a->{fileName} -> $fileName" + . " or open during size fixup\n"); + } else { + my $poolWrite = BackupPC::PoolWrite->new($a->{bpc}, $a->{fileName}, + $a->{fileSize}, $a->{compress}); + my $nRead = 0; + + while ( $nRead < $a->{fileSize} ) { + my $thisRead = $a->{fileSize} - $nRead < $BufSize + ? $a->{fileSize} - $nRead : $BufSize; + my $data; + my $n = $fh->read(\$data, $thisRead); + if ( $n != $thisRead ) { + push(@{$a->{errors}}, + "Unable to read $thisRead bytes during resize" + . " from temp $fileName (got $n)\n"); + last; + } + $poolWrite->write(\$data); + $nRead += $thisRead; + } + $fh->close; + unlink($fileName); + if ( @{$a->{errors}} ) { + $poolWrite->close; + return (0, $a->{digest}, -s $a->{fileName}, $a->{errors}); + } else { + return $poolWrite->close; + } + } + } + if ( $a->{fileSize} == 0 ) { # # Simply create an empty file diff --git a/lib/BackupPC/Xfer/Rsync.pm b/lib/BackupPC/Xfer/Rsync.pm index f6ad740..1d647ac 100644 --- a/lib/BackupPC/Xfer/Rsync.pm +++ b/lib/BackupPC/Xfer/Rsync.pm @@ -29,7 +29,7 @@ # #======================================================================== # -# Version 2.0.0_CVS, released 3 Feb 2003. +# Version 2.0.0beta0, released 23 Feb 2003. # # See http://backuppc.sourceforge.net. # @@ -369,7 +369,9 @@ sub run } else { $t->{xferOK} = 0; } - $t->{xferErrCnt} = $stats->{remoteErrCnt}; + $t->{xferErrCnt} = $stats->{remoteErrCnt} + + $stats->{childStats}{errorCnt} + + $stats->{parentStats}{errorCnt}; $t->{byteCnt} = $stats->{childStats}{TotalFileSize} + $stats->{parentStats}{TotalFileSize}; $t->{fileCnt} = $stats->{childStats}{TotalFileCnt} diff --git a/lib/BackupPC/Xfer/RsyncFileIO.pm b/lib/BackupPC/Xfer/RsyncFileIO.pm index f75fbbb..fdc3625 100644 --- a/lib/BackupPC/Xfer/RsyncFileIO.pm +++ b/lib/BackupPC/Xfer/RsyncFileIO.pm @@ -12,7 +12,7 @@ # #======================================================================== # -# Version 2.0.0_CVS, released 3 Feb 2003. +# Version 2.0.0beta0, released 23 Feb 2003. # # See http://backuppc.sourceforge.net. # @@ -65,6 +65,7 @@ sub new attrib => {}, logHandler => \&logHandler, stats => { + errorCnt => 0, TotalFileCnt => 0, TotalFileSize => 0, ExistFileCnt => 0, @@ -113,6 +114,7 @@ sub csumStart 0, $attr->{compress})) ) { $fio->log("Can't open $attr->{fullPath} (name=$f->{name})"); + $fio->{stats}{errorCnt}++; return -1; } if ( $needMD4) { @@ -133,14 +135,16 @@ sub csumGet return if ( !defined($fio->{fh}) ); if ( $fio->{fh}->read(\$fileData, $blockSize * $num) <= 0 ) { - return; + $fio->log("$fio->{file}{name}: csumGet is at EOF - zero padding\n"); + $fio->{stats}{errorCnt}++; + $fileData = pack("c", 0) x ($blockSize * $num); } $fio->{csumDigest}->add($fileData) if ( defined($fio->{csumDigest}) ); $fio->log(sprintf("%s: getting csum ($num,$csumLen,%d,0x%x)\n", $fio->{file}{name}, length($fileData), $fio->{checksumSeed})) - if ( $fio->{logLevel} >= 10 ); + if ( $fio->{logLevel} >= 9 ); return $fio->{digest}->blockDigest($fileData, $blockSize, $csumLen, $fio->{checksumSeed}); } @@ -175,6 +179,7 @@ sub readStart 0, $attr->{compress})) ) { $fio->log("Can't open $attr->{fullPath} (name=$f->{name})"); + $fio->{stats}{errorCnt}++; return; } $fio->log("$f->{name}: opened for read") if ( $fio->{logLevel} >= 4 ); @@ -489,6 +494,7 @@ sub makePath File::Path::mkpath($path, 0, 0777) if ( !-d $path ); return $fio->attribSet($f) if ( -d $path ); $fio->log("Can't create directory $path"); + $fio->{stats}{errorCnt}++; return -1; } @@ -678,7 +684,7 @@ sub fileDeltaRxNext $rxOutFile, $fio->{rxFile}{size}, $fio->{xfer}{compress}); $fio->log("$fio->{rxFile}{name}: opening output file $rxOutFile") - if ( $fio->{logLevel} >= 10 ); + if ( $fio->{logLevel} >= 9 ); $fio->{rxOutFile} = $rxOutFile; $fio->{rxOutFileRel} = $rxOutFileRel; $fio->{rxDigest} = File::RsyncP::Digest->new; @@ -704,6 +710,7 @@ sub fileDeltaRxNext 0, $attr->{compress})) ) { $fio->log("Can't open $attr->{fullPath}"); + $fio->{stats}{errorCnt}++; return -1; } if ( $attr->{size} < 10 * 1024 * 1024 ) { @@ -715,6 +722,9 @@ sub fileDeltaRxNext while ( $fh->read(\$data, 10 * 1024 * 1024) > 0 ) { $fio->{rxInData} .= $data; } + $fio->log("$attr->{fullPath}: cached all $attr->{size}" + . " bytes") + if ( $fio->{logLevel} >= 9 ); } else { # # Create and write a temporary output file @@ -723,20 +733,27 @@ sub fileDeltaRxNext if ( -f "$fio->{outDirSh}RStmp" ); if ( open(F, "+>", "$fio->{outDirSh}RStmp") ) { my $data; + my $byteCnt = 0; while ( $fh->read(\$data, 1024 * 1024) > 0 ) { if ( syswrite(F, $data) != length($data) ) { $fio->log(sprintf("Can't write len=%d to %s", length($data) , "$fio->{outDirSh}RStmp")); $fh->close; + $fio->{stats}{errorCnt}++; return -1; } + $byteCnt += length($data); } $fio->{rxInFd} = *F; $fio->{rxInName} = "$fio->{outDirSh}RStmp"; seek($fio->{rxInFd}, 0, 0); + $fio->log("$attr->{fullPath}: copied $byteCnt," + . "$attr->{size} bytes to $fio->{rxInName}") + if ( $fio->{logLevel} >= 9 ); } else { $fio->log("Unable to open $fio->{outDirSh}RStmp"); $fh->close; + $fio->{stats}{errorCnt}++; return -1; } } @@ -747,6 +764,7 @@ sub fileDeltaRxNext $fio->{rxInName} = $attr->{fullPath}; } else { $fio->log("Unable to open $attr->{fullPath}"); + $fio->{stats}{errorCnt}++; return -1; } } @@ -757,7 +775,8 @@ sub fileDeltaRxNext if ( $fio->{logLevel} >= 9 ); my $seekPosn = $fio->{rxMatchBlk} * $fio->{rxBlkSize}; if ( defined($fio->{rxInFd}) && !seek($fio->{rxInFd}, $seekPosn, 0) ) { - $fio->log("Unable to seek $attr->{fullPath} to $seekPosn"); + $fio->log("Unable to seek $attr->{rxInName} to $seekPosn"); + $fio->{stats}{errorCnt}++; return -1; } my $cnt = $fio->{rxMatchNext} - $fio->{rxMatchBlk}; @@ -774,10 +793,14 @@ sub fileDeltaRxNext $data = substr($fio->{rxInData}, $seekPosn, $len); $seekPosn += $len; } else { - if ( sysread($fio->{rxInFd}, $data, $len) != $len ) { - $fio->log("Unable to read $len bytes from" - . " $fio->{rxInName} " - . "($i,$thisCnt,$fio->{rxBlkCnt})"); + my $got = sysread($fio->{rxInFd}, $data, $len); + if ( $got != $len ) { + my $inFileSize = -s $fio->{rxInName}; + $fio->log("Unable to read $len bytes from $fio->{rxInName}" + . " got=$got, seekPosn=$seekPosn" + . " ($i,$thisCnt,$fio->{rxBlkCnt},$inFileSize" + . ",$attr->{size})"); + $fio->{stats}{errorCnt}++; return -1; } } @@ -835,7 +858,8 @@ sub fileDeltaRxDone } $fh->close; } else { - # ERROR + $fio->log("cannot open $attr->{fullPath} for MD4 check"); + $fio->{stats}{errorCnt}++; } $fio->log("$name got exact match") if ( $fio->{logLevel} >= 5 ); @@ -893,6 +917,7 @@ sub fileDeltaRxDone . $fio->{bpc}->fileNameMangle($name); if ( !link($attr->{fullPath}, $rxOutFile) ) { $fio->log("Unable to link $attr->{fullPath} to $rxOutFile"); + $fio->{stats}{errorCnt}++; return -1; } # @@ -953,17 +978,19 @@ sub fileListEltSend # $extraAttribs = { rdev => $1 * 256 + $2 }; } else { - # ERROR - $fio->log("$name: unexpected file contents $str"); + $fio->log("$name: unexpected special file contents $str"); + $fio->{stats}{errorCnt}++; } } else { # ERROR $fio->log("$name: can't read exactly $a->{size} bytes"); + $fio->{stats}{errorCnt}++; } $fh->close; } else { # ERROR $fio->log("$name: can't open"); + $fio->{stats}{errorCnt}++; } } my $f = {