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 + -
显示快捷键?