client.c

来自「一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX,」· C语言 代码 · 共 2,638 行 · 第 1/5 页

C
2,638
字号
  if(l > nall)    lstr = ZRENEWP(lstr, UChar, nall = l);  if(!lstr){    errmsg("Error: No memory, where absolutely needed");    return;  }  strcpy(lstr, str);  rm_backspace(lstr);  fp = ((params->mode == MODE_CREATE && save_stdio) ?			params->errfp : params->outfp);  fprintf(fp, "%s", lstr);}voidwrite_reportfile(UChar * filename, AarParams * params, Int32 rc){  FILE		*fp;  UChar		numbuf[50];  Int32		i;  i = unlink(filename);  if(i < 0 && errno && errno != ENOENT){    errmsg(T_("Error: Cannot remove report file `%s'\n"), filename);    return;  }  fp = fopen(filename, "w");  if(!fp){    errmsg(T_("Error: Cannot write report file `%s'\n"), filename);    return;  }  fprintf(fp, T_("Backup statistics:\n"));  fprintf(fp, "==================\n\n");  if(identitystr)    fprintf(fp, T_("Client Identifier:             %s\n\n"), identitystr);  fprintf(fp, T_("Exit Status:                   %ld\n\n"), (long int) rc);  fprintf(fp, T_("Start-Time:                    %s\n"), params->vars.startdate);  fprintf(fp, T_("End-Time:                      %s\n\n"), params->vars.enddate);  fprintf(fp, T_("Backup Server:                 %s\n"), servername);  fprintf(fp, T_("Backup Port:                   %d\n"), (int) portnum);  fprintf(fp, T_("First Cartridge used:          %ld\n"), (long int) params->vars.firstcart);  fprintf(fp, T_("First Tapefile accessed:       %ld\n"), (long int) params->vars.firstfile);  fprintf(fp, T_("Last Cartridge used:           %ld\n"), (long int) params->vars.lastcart);  fprintf(fp, T_("Last Tapefile accessed:        %ld\n"), (long int) params->vars.lastfile);  fprintf(fp, "%-31s", T_("Used Cartridges:"));  fprint_Uns32Ranges(fp, params->vars.used_carts, 0); fprintf(fp, "\n\n");  fprintf(fp, T_("Stored filesystem entries:     %ld\n"), (long int) params->vars.num_fsentries);  fprintf(fp, T_("Bytes written to media:        %s\n"),		Real64_to_intstr(params->vars.bytes_saved, numbuf));  fprintf(fp, T_("Sum of filesizes:              %s\n"),		Real64_to_intstr(params->vars.sum_filesizes, numbuf));  fprintf(fp, T_("Sum of compressed filesizes:   %s\n"),		Real64_to_intstr(params->vars.sum_compr_filesizes, numbuf));  fprintf(fp, T_("Sum of uncompressed filesizes: %s\n"),		Real64_to_intstr(params->vars.sum_uncompr_filesizes, numbuf));  if(params->vars.sum_compr_filesizes > 0){    fprintf(fp, T_("Total compression factor:      %.2f\n"),		(float) params->vars.sum_filesizes /		(float) (params->vars.sum_compr_filesizes				+ params->vars.sum_uncompr_filesizes));    fprintf(fp, T_("Real compression factor:       %.2f\n"),		(float) (params->vars.sum_filesizes -				params->vars.sum_uncompr_filesizes) /		(float) (params->vars.sum_compr_filesizes));  }  fprintf(fp, "\n");  fclose(fp);}Int32		/* buffered mode not supported for this function */add_written_tapes(Uns32Range ** alltapes){  Uns32Range	*newtapes = NULL;  UChar		*instr = NULL, buf[4];  Int32		i, r = 0;  if( (i = send_cmd(QUERYWRITTENTAPES)) )    return(i);  if(read_forced(commfd, buf, 4) != 4)    return(- errno);  bytes_transferred += ESTIM_PROT_OVERHEAD + 4;  xref_to_Uns32(&i, buf);  if(!i)    return(result());  instr = NEWP(UChar, i + 1);  if(!instr){    r = - errno;    GETOUT;  }  if( (r = (read_forced(commfd, instr, i) != i ? - errno : 0)) )    GETOUT;  instr[i] = '\0';  bytes_transferred += ESTIM_PROT_OVERHEAD + i;  if(!(newtapes = sscan_Uns32Ranges(instr, 0, 0, NULL, NULL))){    r = - errno;    GETOUT;  }  if(alltapes)    r = merge_Uns32Ranges(alltapes, newtapes);  else{    *alltapes = newtapes;    newtapes = NULL;  } getout:  ZFREE(instr);  ZFREE(newtapes);  i = result();  return(r ? r : i);}Int32create_command_queue(){    Int32	required_entry_mem, i;#ifndef	_WIN32    struct rlimit	rlim;#endif    max_outarglen = max_inresultlen = commbufsiz + 4;    required_entry_mem = max_outarglen + max_inresultlen + sizeof(QueueEntry);#ifndef	_WIN32    i = getrlimit(RLIMIT_STACK, &rlim);    if(i){	errmsg("Error: cannot get maximum available memory");    }    queuelen = rlim.rlim_cur / required_entry_mem / 4;#else    queuelen = 1000000 / required_entry_mem / 4;#endif    if(queuelen < 1){	comm_mode = SERIAL_OPERATION;    }    else{	if(required_entry_mem * queuelen > MAX_QUEUE_MEMORY){	  queuelen = MAX_QUEUE_MEMORY / required_entry_mem;	}	if(max_outarglen * queuelen < 100000){	  comm_mode = SERIAL_OPERATION;	}	else{	  allocated_outmem = max_outarglen * queuelen;	  allocated_inmem = max_inresultlen * queuelen;	  outbufmem = NEWP(UChar, allocated_outmem);	  inbufmem = NEWP(UChar, allocated_inmem);	  queue_entries = NEWP(QueueEntry, queuelen);	  if(!outbufmem || !inbufmem || !queue_entries){	    errmsg("Error: Strange. Can't get memory. Disabling queued operation");	    comm_mode = SERIAL_OPERATION;	    allocated_outmem = allocated_inmem = 0;	    ZFREE(outbufmem);	    ZFREE(inbufmem);	    ZFREE(queue_entries);	  }	  else{	    params.readfunc = queued_read;	    params.writefunc = queued_write;	    memset(queue_entries, 0, queuelen * sizeof(QueueEntry));	  }	}    }    max_queuelen = queuelen;    queueent_done_idx = queueent_requested_idx = queueent_processed_idx			= queue_insert_idx = 0;    queue_commbufsiz = commbufsiz;    return(0);}Int32delete_command_queue(){  Int32		r = 0;  if(QUEUEDOP)    r = post_process_rest_of_queue(0);  comm_mode = SERIAL_OPERATION;  ZFREE(outbufmem);  ZFREE(inbufmem);  ZFREE(queue_entries);  queuelen = 0;  allocated_outmem = allocated_inmem = 0;  params.readfunc = read_forced;  params.writefunc = write_forced;  return(r);}voidgive_help(){	/* automatically generated: */{char *l[327];int i;l[0]=T_("Description");l[1]=T_("===========");l[2]="";l[3]=T_("This program is used to maintain archives on a backup server");l[4]=T_("host or in a file. Archives can be created, extracted or their");l[5]=T_("contents be listed. At least one of the following flags has to");l[6]=T_("be supplied:");l[7]="";l[8]=T_(" -c  to create an archive");l[9]="";l[10]=T_(" -x  to extract from an archive");l[11]="";l[12]=T_(" -t  to list the contents of an archive");l[13]="";l[14]=T_(" -d  to verify (compare) the contents of an archive");l[15]="";l[16]=T_(" -C  to set a certain cartridge on the backup server");l[17]=T_("       (makes only sense extracting or listing with -x or");l[18]=T_("        -t, the writing position can't be changed by clients)");l[19]="";l[20]=T_(" -F  to set a certain file on the backup server's tape");l[21]=T_("       (the same applies as for -C)");l[22]="";l[23]=T_(" -q  to printout the current cartridge and tape file number");l[24]=T_("       on the backup server");l[25]="";l[26]=T_(" -Q  to printout the cartridge and tape file number for the");l[27]=T_("       the next write access on the backup server");l[28]="";l[29]=T_(" -X  followed by the full path name of a program to be started on");l[30]=T_("       the client. This can be used to trigger a backup remotely.");l[31]=T_("       If the program needs arguments, the command together with");l[32]=T_("       the arguments has to be enclosed by quotes");l[33]="";l[34]=T_(" -I  to printout an index of the backups written to the current");l[35]=T_("       cartridge");l[36]="";l[37]=T_(" -w  to check the status of the streamer on the server side, e.g.");l[38]=T_("       whether it is ready and waiting for requests to service");l[39]="";l[40]=T_(" -G  to request a new cartridge for the next writing operation.");l[41]=T_("       If the current writing position is already at the beginning");l[42]=T_("       of a new or reused tape, nothing happens");l[43]="";l[44]=T_(" -D <destination> to make an exact copy of a tape to another one");l[45]=T_("       (duplicate). See below how to specify the destination tape.");l[46]=T_("       Duplication can be either from one cartridge to another on");l[47]=T_("       the same server, or from one server to another one. When");l[48]=T_("       copying to the same server chunks of data are stored in a");l[49]=T_("       temporary directory on the client, where the command is");l[50]=T_("       started, what should preferably be the source server");l[51]="";l[52]=T_(" -M <message> send a message to the server. Messages will in the");l[53]=T_("       most cases contain whitespace, so they should be enclosed");l[54]=T_("       in quotes. Server messages should be sent to the single");l[55]=T_("       stream server (port), the multi stream server might hang");l[56]=T_("       receiving a message due to systematical reasons. Several");l[57]=T_("       messages can be put into the string. They must be separated");l[58]=T_("       by a real newline character or the usual C-like \\n .");l[59]=T_("       The following messages are currently supported:");l[60]="";l[61]=T_("        PreciousTapes: <list-of-tapes>");l[62]=T_("                   The list of tapes is inserted into the table");l[63]=T_("                   with the tapes, that are crucial for clients");l[64]=T_("                   to restore all files, that are listed in all");l[65]=T_("                   existing index files. These tapes will not be");l[66]=T_("                   overwritten until explicitly permitted. This");l[67]=T_("                   message is generated automatically and should");l[68]=T_("                   not be used in other user contexts");l[69]="";l[70]=T_("        ReuseTapes: <list-of-tapes>");l[71]=T_("                   The opposite of PreciousTapes. Sending this");l[72]=T_("                   message permits the server to overwrite the");l[73]=T_("                   listed tapes, though they are crucial for");l[74]=T_("                   some client");l[75]="";l[76]=T_("        TapesReadOnly: <list-of-tapes>");l[77]=T_("                   The list of tapes is inserted into the file");l[78]=T_("                   listing the files, that should not be written");l[79]=T_("                   any more for whatever reason");l[80]="";l[81]=T_("        TapesReadWrite: <list-of-tapes>");l[82]=T_("                   This reverts the status of tapes set read-only");l[83]=T_("                   to read-write, the opposite of TapesReadOnly");l[84]="";l[85]=T_("        CartridgeReady");l[86]=T_("                   When an operator is requested to do something");l[87]=T_("                   the server is waiting for, this message can be");l[88]=T_("                   sent to trigger the server to proceed. This");l[89]=T_("                   message has the same effect as the cartready");l[90]=T_("                   command");l[91]="";l[92]=T_("        DeleteClient: <client-identifier>");l[93]=T_("                   The tapes, that are marked as reserved for a");l[94]=T_("                   client to recover all the data in his indexes,");l[95]=T_("                   are freed. That is, the appropriate line is");l[96]=T_("                   removed from the server's precious_tapes file");l[97]="";l[98]=T_(" -m [ <interval> ] poll the current message from the server and");l[99]=T_("       write it to standard output, if it is new. Polling is");l[100]=T_("       done indefinitely with the given interval in seconds,");l[101]=T_("       default interval is 3 seconds");l[102]="";l[103]=T_("-c, -x, -t, -d, -X, -D, -I and -m are mutual exclusive. The other");l[104]=T_("options can be supplied as needed. To set the cartridge and/or");l[105]=T_("the tape file on the backup server is only making sense when not");l[106]=T_("creating an archive. The serial order of writing to tape is");l[107]=T_("handled by the server machine independently of the client.");l[108]="";l[109]="";l[110]=T_("Filenames");l[111]="";l[112]=T_("The names of the files and directories, that have to be put");l[113]=T_("into or extracted from an archive are by default read from the");l[114]=T_("standard input. If filenames are supplied in the command line");l[115]=T_("the -a flag is given when extracting, standard input is not read.");l[116]=T_("The same applies, when filenames are read from a file with the");l[117]=T_("-T option. When reading the names from a file or from standard");l[118]=T_("input, they must be given one per line. If a name contains");l[119]=T_("special characters (like newline or nonprintable ones), they");l[120]=T_("have to be specified using backslash-sequences like in C-code,");l[121]=T_("e.g. \\n for newline.");l[122]=T_("In save mode (-c) filenames can be prefixed with character");l[123]=T_("sequences, that have special meanings (no space between prefix");l[124]=T_("and filename):");l[125]="";l[126]=T_(" /../   The file is not saved with all attributes present in");l[127]=T_("        the inode, but only the contents are saved. This might");l[128]=T_("        be useful for saving raw-devices");l[129]=T_(" //../  With /../ the configured processing is not applied to");l[130]=T_("        the file contents for safety reasons. With this prefix");l[131]=T_("        processing can be forced nonetheless");l[132]=T_(" |||    and a mandatory space character indicates, that the");l[133]=T_("        following characters up to (but not including) another");l[134]=T_("        triple bar ||| should be interpreted as a shell command,");l[135]=T_("        that is started and whose standard output is written to");l[136]=T_("        the backup. At restore time the command following the");l[137]=T_("        second triple bar is started and the data stream read");l[138]=T_("        at backup time is written to it's standard input. This");l[139]=T_("        might be useful for saving e.g. databases. The second");l[140]=T_("        command may be terminated by a triple sharp ###, that");l[141]=T_("        starts an optional comment. Example:");l[142]=T_("        ||| pg_dumpall ||| psql db_tmpl ### Store Postgres DBs");l[143]="";l[144]="";l[145]=T_("Destination");l[146]="";l[147]=T_("The destination tape for the duplicate operation can be given");l[148]=T_("in two ways: either with the options -h, -p, -C and -k following");l[149]=T_("the -D immediately without space and enclosed in quotes, so that");l[150]=T_("they appear as an own argument list in one real argument, e.g.:");l[151]=T_(" -D' -C 5 -h targethost -p targetport'");l[152]=T_("(double quotes are of course also possible ...).");l[153]=T_("The second format is as follows:");l[154]=T_(" [<targetcart>][@<targethost>][%targetport>][:<targetcryptkeyfile>]");l[155]=T_("At least one of the specifiers must be present. Examples:");l[156]=T_(" 5@otherhost  5%2990:/keyfile/for/target/server @otherhost%2970");l[157]=T_("If one of the specifiers is omitted, it is assumed identical with");l[158]=T_("the copy source specified in the normal options -h, -p, -C and -k.");l[159]=T_("Copying a tape to itself is prevented.");l[160]="";l[161]="";l[162]=T_("More options in alphabetical order:");l[163]="";l[164]=T_(" -            in combination with -c: read standard input and");l[165]=T_("                write it to tape, in combination with -x: read");l[166]=T_("                tape and write it to standard output");l[167]="";l[168]=T_(" -A <time>    process files (save or extract) modified after");l[169]=T_("                the given time in seconds since 1.1.1970 00:00");l[170]="";l[171]=T_(" -a           in combination with -x: extract all files and");l[172]=T_("                directories in the archive");l[173]="";l[174]=T_(" -B <time>    process files (save or extract) modified before");l[175]=T_("                the given time in seconds since 1.1.1970 00:00");l[176]="";l[177]=T_(" -b           don't enter buffering mode");l[178]="";l[179]=T_(" -e <errlog>  Use the file <errlog> to write error messages to");l[180]=T_("                instead of the standard error output");l[181]="";l[182]=T_(" -f <file>    write to or read from a file instead of querying");l[183]=T_("                the backup server");l[184]="";l[185]=T_(" -g           while extracting/reading: ignore leading garbage,");l[186]=T_("                suppress error messages at the beginning. This");l[187]=T_("                is useful when extracting from tape files, that");l[188]=T_("                are not the first ones of a whole archive.");l[189]="";l[190]=T_(" -H <header>  put the supplied informational header to the begin");l[191]=T_("                of the backup. If a - is supplied (no space may");l[192]=T_("                follow -H i.e. -H-) the information is read from");l[193]=T_("                the first line of stdin. Backslash sequences of");l[194]=T_("                C-like style are replaced");l[195]="";l[196]=T_(" -h <host>    use the backup server with the name <host>");l[197]=T_("                default host is the machine with the name");l[198]=T_("                backuphost");l[199]="";l[200]=T_(" -i           while extracting: ignore the stored ownership and");l[201]=T_("                do not restore it");l[202]="";l[203]=T_(" -j           when starting to write: request starting a new");l[204]=T_("                tape file");l[205]="";l[206]=T_(" -K           when packing, do not keep the access time of the");l[207]=T_("                file. By default after packing a filesystem entry");l[208]=T_("                it's previous atime is restored");l[209]="";l[210]=T_(" -k <file>    use the contents of the given file as encryption");l[211]=T_("                key for authenticating to the server");l[212]="";l[213]=T_(" -l           for each packed or unpacked filename, if sending");l[214]=T_("                to or receiving from a backup server in verbose");l[215]=T_("                   mode in combination with -n:");l[216]=T_("                printout server name and port number at the");l[217]=T_("                beginning of the line, e.g.: orion%2988!");l[218]="";l[219]=T_(" -N <file>    while archiving: ignore files with a modification");l[220]=T_("                time before the one of the given file, only save");l[221]=T_("                newer files or such with the same age in seconds");l[222]="";l[223]=T_(" -n           for each packed or unpacked filename, if sending");l[224]=T_("                to or receiving from a backup server in verbose");l[225]=T_("                   mode:");l[226]=T_("                printout cartridge and tape file number at the");l[227]=T_("                beginning of the line, e. g.: 7.15: <filename>");l[228]=T_("                In combination with -X: precede each line of");l[229]=T_("                output received from the remotely started program");l[230]=T_("                with the identifier of the remote host and a");l[231]=T_("                colon, e. g.:  darkstar: Full backup finished.");l[232]="";l[233]=T_(" -O           for each packed file creating a backup in verbose");l[234]=T_("                mode: printout the user-ID of the file owner at");l[235]=T_("                the beginning of the line prefixed with a bar |");l[236]=T_("                eventually behind cartridge and file number");l[237]="";l[238]=T_(" -o <uid>     archive or extract only files owned by the user");l[239]=T_("                with the given user-ID (an integer)");l[240]="";l[241]=T_(" -p <portno>  use a different port number for communicating with");l[242]=T_("                the backup server. Default is TCP-Port 2988");l[243]="";l[244]=T_(" -R           pack or extract directories recursively with all");l[245]=T_("                of their contents");l[246]="";l[247]=T_(" -r           use filenames relative to the current directory,");l[248]=T_("                whether they start with a slash or not. If -r");l[249]=T_("                is given more then 1 time, also let symlinks");l[250]=T_("                originally pointing to absolute paths now point");l[251]=T_("                to paths relative to the directory, where the");l[252]=T_("                symlink will be created");l[253]="";l[254]=T_(" -S <cartset> The cartridge set to use, where <cartset> is the");l[255]=T_("                number of a valid cartridge set on the server");l[256]=T_("                side. Default is 1. This option makes sense only");l[257]=T_("                when creating backups with -c");l[258]="";l[259]=T_(" -s <filepat> do not attempt processing on files matching the");l[260]=T_("                given filename pattern. This parameter may");l[261]=T_("                appear several times");l[262]="";l[263]=T_(" -T <file/dir> read the filenames to process from the <file>.");l[264]=T_("                The filenames must be separated by whitespace.");l[265]=T_("                If whitespace is part of a filename, it has to");l[266]=T_("                be enclosed by double quotes. Double quotes or");l[267]=T_("                backslashes within the filename have to be");l[268]=T_("                preceded by a backslash. In combination with");l[269]=T_("                -D: the tape files to be copied are temporarily");l[270]=T_("                stored in the given directory instead of the");l[271]=T_("                default directory /tmp");l[272]="";l[273]=T_(" -U           for each packed file creating a backup in verbose");l[274]=T_("                mode: printout the modification time of the file");l[275]=T_("                in seconds since 1970/1/1 0:00 at the beginning");l[276]=T_("                of the line prefixed with a tilde ~ eventually");l[277]=T_("                behind cartridge number, file number and owner");l[278]="";l[279]=T_(" -u           while extracting: remove existing files with the");l[280]=T_("                same name as found in the archive. Otherwise");l[281]=T_("                no existing files are overwritten");l[282]="";l[283]=T_(" -V <file>    write a report containing statistics at the end of");l[284]=T_("                a backup to the <file>");l[285]="";l[286]=T_(" -v           verbose mode: print the filenames while creating");l[287]=T_("                or extracting, be a little more verbose while");l[288]=T_("                listing contents. If -v is the only given flag:");l[289]=T_("                print out software name and version");l[290]="";l[291]=T_(" -W <id>      identify as <id> to the server. This is needed when");l[292]=T_("                connecting a multi-stream server to distinguish");l[293]=T_("                between the clients. Default is the string");l[294]=T_("                \"<client-program>\"");l[295]="";l[296]=T_(" -z <z> <uz>  use <z> as the command, that is used to process");l[297]=T_("                files, <uz> for the corresponding unprocess.");l[298]=T_("                The command has to read from stdin and to write");l[299]=T_("                to stdout. If arguments have to be supplied to");l[300]=T_("                <z> and/or <uz>, don't forget to use quotes. If");l[301]=T_("                built-in compression is desired, the command for");l[302]=T_("                processing has to start with a dot (.), followed");l[303]=T_("                by a space and a number ranging from 1 to 9, that");l[304]=T_("                specifies the compression level. If an additional");l[305]=T_("                external command should process the data, it may");l[306]=T_("                follow, separated from the compression le

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?