\doxysubsection{patch.\+c}
\label{patch_8c_source}\index{patch.c@{patch.c}}
\mbox{\hyperlink{patch_8c}{Go to the documentation of this file.}}
\begin{DoxyCode}{0}
\DoxyCodeLine{00001 \textcolor{comment}{/*= -\/*-\/ c-\/basic-\/offset: 4; indent-\/tabs-\/mode: nil; -\/*-\/}}
\DoxyCodeLine{00002 \textcolor{comment}{ *}}
\DoxyCodeLine{00003 \textcolor{comment}{ * librsync -\/-\/ the library for network deltas}}
\DoxyCodeLine{00004 \textcolor{comment}{ *}}
\DoxyCodeLine{00005 \textcolor{comment}{ * Copyright (C) 2000, 2001 by Martin Pool <mbp@sourcefrog.net>}}
\DoxyCodeLine{00006 \textcolor{comment}{ *}}
\DoxyCodeLine{00007 \textcolor{comment}{ * This program is free software; you can redistribute it and/or}}
\DoxyCodeLine{00008 \textcolor{comment}{ * modify it under the terms of the GNU Lesser General Public License}}
\DoxyCodeLine{00009 \textcolor{comment}{ * as published by the Free Software Foundation; either version 2.1 of}}
\DoxyCodeLine{00010 \textcolor{comment}{ * the License, or (at your option) any later version.}}
\DoxyCodeLine{00011 \textcolor{comment}{ *}}
\DoxyCodeLine{00012 \textcolor{comment}{ * This program is distributed in the hope that it will be useful, but}}
\DoxyCodeLine{00013 \textcolor{comment}{ * WITHOUT ANY WARRANTY; without even the implied warranty of}}
\DoxyCodeLine{00014 \textcolor{comment}{ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU}}
\DoxyCodeLine{00015 \textcolor{comment}{ * Lesser General Public License for more details.}}
\DoxyCodeLine{00016 \textcolor{comment}{ *}}
\DoxyCodeLine{00017 \textcolor{comment}{ * You should have received a copy of the GNU Lesser General Public}}
\DoxyCodeLine{00018 \textcolor{comment}{ * License along with this program; if not, write to the Free Software}}
\DoxyCodeLine{00019 \textcolor{comment}{ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.}}
\DoxyCodeLine{00020 \textcolor{comment}{ */}}
\DoxyCodeLine{00021 }
\DoxyCodeLine{00022                               \textcolor{comment}{/*=}}
\DoxyCodeLine{00023 \textcolor{comment}{                               | This is Tranquility Base.}}
\DoxyCodeLine{00024 \textcolor{comment}{                               */}}
\DoxyCodeLine{00025 \textcolor{comment}{}}
\DoxyCodeLine{00026 \textcolor{comment}{/** \(\backslash\)file patch.c}}
\DoxyCodeLine{00027 \textcolor{comment}{ * Apply a delta to an old file to generate a new file. */}}
\DoxyCodeLine{00028 }
\DoxyCodeLine{00029 \textcolor{preprocessor}{\#include "{}config.h"{}}             \textcolor{comment}{/* IWYU pragma: keep */}}
\DoxyCodeLine{00030 \textcolor{preprocessor}{\#include <assert.h>}}
\DoxyCodeLine{00031 \textcolor{preprocessor}{\#include <stdlib.h>}}
\DoxyCodeLine{00032 \textcolor{preprocessor}{\#include <string.h>}}
\DoxyCodeLine{00033 \textcolor{preprocessor}{\#include <stdint.h>}}
\DoxyCodeLine{00034 \textcolor{preprocessor}{\#include "{}librsync.h"{}}}
\DoxyCodeLine{00035 \textcolor{preprocessor}{\#include "{}job.h"{}}}
\DoxyCodeLine{00036 \textcolor{preprocessor}{\#include "{}netint.h"{}}}
\DoxyCodeLine{00037 \textcolor{preprocessor}{\#include "{}scoop.h"{}}}
\DoxyCodeLine{00038 \textcolor{preprocessor}{\#include "{}command.h"{}}}
\DoxyCodeLine{00039 \textcolor{preprocessor}{\#include "{}prototab.h"{}}}
\DoxyCodeLine{00040 \textcolor{preprocessor}{\#include "{}trace.h"{}}}
\DoxyCodeLine{00041 }
\DoxyCodeLine{00042 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_cmdbyte(rs\_job\_t *);}
\DoxyCodeLine{00043 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_params(rs\_job\_t *);}
\DoxyCodeLine{00044 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_run(rs\_job\_t *);}
\DoxyCodeLine{00045 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_literal(rs\_job\_t *);}
\DoxyCodeLine{00046 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_copy(rs\_job\_t *);}
\DoxyCodeLine{00047 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_copying(rs\_job\_t *);}
\DoxyCodeLine{00048 \textcolor{comment}{}}
\DoxyCodeLine{00049 \textcolor{comment}{/** State of trying to read the first byte of a command. Once we've taken that}}
\DoxyCodeLine{00050 \textcolor{comment}{ * in, we can know how much data to read to get the arguments. */}}
\DoxyCodeLine{00051 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_cmdbyte(rs\_job\_t *job)}
\DoxyCodeLine{00052 \{}
\DoxyCodeLine{00053     rs\_result result;}
\DoxyCodeLine{00054 }
\DoxyCodeLine{00055     \textcolor{keywordflow}{if} ((result = rs\_suck\_byte(job, \&job-\/>op)) != RS\_DONE)}
\DoxyCodeLine{00056         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00057     job-\/>cmd = \&rs\_prototab[job-\/>op];}
\DoxyCodeLine{00058     rs\_trace(\textcolor{stringliteral}{"{}got command \%\#04x (\%s), len\_1=\%d, len\_2=\%d"{}}, job-\/>op,}
\DoxyCodeLine{00059              rs\_op\_kind\_name(job-\/>cmd-\/>kind), job-\/>cmd-\/>len\_1, job-\/>cmd-\/>len\_2);}
\DoxyCodeLine{00060     \textcolor{keywordflow}{if} (job-\/>cmd-\/>len\_1)}
\DoxyCodeLine{00061         job-\/>statefn = rs\_patch\_s\_params;}
\DoxyCodeLine{00062     \textcolor{keywordflow}{else} \{}
\DoxyCodeLine{00063         job-\/>param1 = job-\/>cmd-\/>immediate;}
\DoxyCodeLine{00064         job-\/>statefn = rs\_patch\_s\_run;}
\DoxyCodeLine{00065     \}}
\DoxyCodeLine{00066     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00067 \}}
\DoxyCodeLine{00068 \textcolor{comment}{}}
\DoxyCodeLine{00069 \textcolor{comment}{/** Called after reading a command byte to pull in its parameters and then}}
\DoxyCodeLine{00070 \textcolor{comment}{ * setup to execute the command. */}}
\DoxyCodeLine{00071 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_params(rs\_job\_t *job)}
\DoxyCodeLine{00072 \{}
\DoxyCodeLine{00073     rs\_result result;}
\DoxyCodeLine{00074     \textcolor{keyword}{const} \textcolor{keywordtype}{size\_t} len = (size\_t)(job-\/>cmd-\/>len\_1 + job-\/>cmd-\/>len\_2);}
\DoxyCodeLine{00075     \textcolor{keywordtype}{void} *p;}
\DoxyCodeLine{00076 }
\DoxyCodeLine{00077     assert(len);}
\DoxyCodeLine{00078     result = rs\_scoop\_readahead(job, len, \&p);}
\DoxyCodeLine{00079     \textcolor{keywordflow}{if} (result != RS\_DONE)}
\DoxyCodeLine{00080         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00081     \textcolor{comment}{/* we now must have LEN bytes buffered */}}
\DoxyCodeLine{00082     result = rs\_suck\_netint(job, \&job-\/>param1, job-\/>cmd-\/>len\_1);}
\DoxyCodeLine{00083     \textcolor{comment}{/* shouldn't fail, since we already checked */}}
\DoxyCodeLine{00084     assert(result == RS\_DONE);}
\DoxyCodeLine{00085     \textcolor{keywordflow}{if} (job-\/>cmd-\/>len\_2) \{}
\DoxyCodeLine{00086         result = rs\_suck\_netint(job, \&job-\/>param2, job-\/>cmd-\/>len\_2);}
\DoxyCodeLine{00087         assert(result == RS\_DONE);}
\DoxyCodeLine{00088     \}}
\DoxyCodeLine{00089     job-\/>statefn = rs\_patch\_s\_run;}
\DoxyCodeLine{00090     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00091 \}}
\DoxyCodeLine{00092 \textcolor{comment}{}}
\DoxyCodeLine{00093 \textcolor{comment}{/** Called when we've read in the whole command and we need to execute it. */}}
\DoxyCodeLine{00094 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_run(rs\_job\_t *job)}
\DoxyCodeLine{00095 \{}
\DoxyCodeLine{00096     rs\_trace(\textcolor{stringliteral}{"{}running command \%\#04x"{}}, job-\/>op);}
\DoxyCodeLine{00097     \textcolor{keywordflow}{switch} (job-\/>cmd-\/>kind) \{}
\DoxyCodeLine{00098     \textcolor{keywordflow}{case} RS\_KIND\_LITERAL:}
\DoxyCodeLine{00099         job-\/>statefn = rs\_patch\_s\_literal;}
\DoxyCodeLine{00100         \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00101     \textcolor{keywordflow}{case} RS\_KIND\_END:}
\DoxyCodeLine{00102         \textcolor{keywordflow}{return} RS\_DONE;}
\DoxyCodeLine{00103         \textcolor{comment}{/* so we exit here; trying to continue causes an error */}}
\DoxyCodeLine{00104     \textcolor{keywordflow}{case} RS\_KIND\_COPY:}
\DoxyCodeLine{00105         job-\/>statefn = rs\_patch\_s\_copy;}
\DoxyCodeLine{00106         \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00107     \textcolor{keywordflow}{default}:}
\DoxyCodeLine{00108         rs\_error(\textcolor{stringliteral}{"{}bogus command \%\#04x"{}}, job-\/>op);}
\DoxyCodeLine{00109         \textcolor{keywordflow}{return} RS\_CORRUPT;}
\DoxyCodeLine{00110     \}}
\DoxyCodeLine{00111 \}}
\DoxyCodeLine{00112 \textcolor{comment}{}}
\DoxyCodeLine{00113 \textcolor{comment}{/** Called when trying to copy through literal data. */}}
\DoxyCodeLine{00114 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_literal(rs\_job\_t *job)}
\DoxyCodeLine{00115 \{}
\DoxyCodeLine{00116     \textcolor{keyword}{const} rs\_long\_t len = job-\/>param1;}
\DoxyCodeLine{00117     rs\_stats\_t *stats = \&job-\/>stats;}
\DoxyCodeLine{00118 }
\DoxyCodeLine{00119     rs\_trace(\textcolor{stringliteral}{"{}LITERAL(length="{}} FMT\_LONG \textcolor{stringliteral}{"{})"{}}, len);}
\DoxyCodeLine{00120     \textcolor{keywordflow}{if} (len <= 0 || len > SIZE\_MAX) \{}
\DoxyCodeLine{00121         rs\_error(\textcolor{stringliteral}{"{}invalid length="{}} FMT\_LONG \textcolor{stringliteral}{"{} on LITERAL command"{}}, len);}
\DoxyCodeLine{00122         \textcolor{keywordflow}{return} RS\_CORRUPT;}
\DoxyCodeLine{00123     \}}
\DoxyCodeLine{00124     stats-\/>lit\_cmds++;}
\DoxyCodeLine{00125     stats-\/>lit\_bytes += len;}
\DoxyCodeLine{00126     stats-\/>lit\_cmdbytes += 1 + job-\/>cmd-\/>len\_1;}
\DoxyCodeLine{00127     rs\_tube\_copy(job, (\textcolor{keywordtype}{size\_t})len);}
\DoxyCodeLine{00128     job-\/>statefn = rs\_patch\_s\_cmdbyte;}
\DoxyCodeLine{00129     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00130 \}}
\DoxyCodeLine{00131 }
\DoxyCodeLine{00132 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_copy(rs\_job\_t *job)}
\DoxyCodeLine{00133 \{}
\DoxyCodeLine{00134     \textcolor{keyword}{const} rs\_long\_t pos = job-\/>param1;}
\DoxyCodeLine{00135     \textcolor{keyword}{const} rs\_long\_t len = job-\/>param2;}
\DoxyCodeLine{00136     rs\_stats\_t *stats = \&job-\/>stats;}
\DoxyCodeLine{00137 }
\DoxyCodeLine{00138     rs\_trace(\textcolor{stringliteral}{"{}COPY(position="{}} FMT\_LONG \textcolor{stringliteral}{"{}, length="{}} FMT\_LONG \textcolor{stringliteral}{"{})"{}}, pos, len);}
\DoxyCodeLine{00139     \textcolor{keywordflow}{if} (len <= 0) \{}
\DoxyCodeLine{00140         rs\_error(\textcolor{stringliteral}{"{}invalid length="{}} FMT\_LONG \textcolor{stringliteral}{"{} on COPY command"{}}, len);}
\DoxyCodeLine{00141         \textcolor{keywordflow}{return} RS\_CORRUPT;}
\DoxyCodeLine{00142     \}}
\DoxyCodeLine{00143     \textcolor{keywordflow}{if} (pos < 0) \{}
\DoxyCodeLine{00144         rs\_error(\textcolor{stringliteral}{"{}invalid position="{}} FMT\_LONG \textcolor{stringliteral}{"{} on COPY command"{}}, pos);}
\DoxyCodeLine{00145         \textcolor{keywordflow}{return} RS\_CORRUPT;}
\DoxyCodeLine{00146     \}}
\DoxyCodeLine{00147     stats-\/>copy\_cmds++;}
\DoxyCodeLine{00148     stats-\/>copy\_bytes += len;}
\DoxyCodeLine{00149     stats-\/>copy\_cmdbytes += 1 + job-\/>cmd-\/>len\_1 + job-\/>cmd-\/>len\_2;}
\DoxyCodeLine{00150     job-\/>basis\_pos = pos;}
\DoxyCodeLine{00151     job-\/>basis\_len = len;}
\DoxyCodeLine{00152     job-\/>statefn = rs\_patch\_s\_copying;}
\DoxyCodeLine{00153     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00154 \}}
\DoxyCodeLine{00155 \textcolor{comment}{}}
\DoxyCodeLine{00156 \textcolor{comment}{/** Called when we're executing a COPY command and waiting for all the data to}}
\DoxyCodeLine{00157 \textcolor{comment}{ * be retrieved from the callback. */}}
\DoxyCodeLine{00158 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_copying(rs\_job\_t *job)}
\DoxyCodeLine{00159 \{}
\DoxyCodeLine{00160     rs\_result result;}
\DoxyCodeLine{00161     rs\_buffers\_t *buffs = job-\/>stream;}
\DoxyCodeLine{00162     rs\_long\_t req = job-\/>basis\_len;}
\DoxyCodeLine{00163     \textcolor{keywordtype}{size\_t} len = buffs-\/>avail\_out;}
\DoxyCodeLine{00164     \textcolor{keywordtype}{void} *ptr = buffs-\/>next\_out;}
\DoxyCodeLine{00165 }
\DoxyCodeLine{00166     \textcolor{comment}{/* We are blocked if there is no space left to copy into. */}}
\DoxyCodeLine{00167     \textcolor{keywordflow}{if} (!len)}
\DoxyCodeLine{00168         \textcolor{keywordflow}{return} RS\_BLOCKED;}
\DoxyCodeLine{00169     \textcolor{comment}{/* Adjust request to min of amount requested and space available. */}}
\DoxyCodeLine{00170     \textcolor{keywordflow}{if} ((rs\_long\_t)len < req)}
\DoxyCodeLine{00171         req = (rs\_long\_t)len;}
\DoxyCodeLine{00172     rs\_trace(\textcolor{stringliteral}{"{}copy "{}} FMT\_LONG \textcolor{stringliteral}{"{} bytes from basis at offset "{}} FMT\_LONG \textcolor{stringliteral}{"{}"{}}, req,}
\DoxyCodeLine{00173              job-\/>basis\_pos);}
\DoxyCodeLine{00174     len = (size\_t)req;}
\DoxyCodeLine{00175     result = (job-\/>copy\_cb) (job-\/>copy\_arg, job-\/>basis\_pos, \&len, \&ptr);}
\DoxyCodeLine{00176     \textcolor{keywordflow}{if} (result != RS\_DONE) \{}
\DoxyCodeLine{00177         rs\_trace(\textcolor{stringliteral}{"{}copy callback returned \%s"{}}, rs\_strerror(result));}
\DoxyCodeLine{00178         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00179     \}}
\DoxyCodeLine{00180     rs\_trace(\textcolor{stringliteral}{"{}got "{}} FMT\_SIZE \textcolor{stringliteral}{"{} bytes back from basis callback"{}}, len);}
\DoxyCodeLine{00181     \textcolor{comment}{/* Actual copied length cannot be greater than requested length. */}}
\DoxyCodeLine{00182     assert(len <= req);}
\DoxyCodeLine{00183     \textcolor{comment}{/* Backwards-\/compatible defensively handle this for NDEBUG builds. */}}
\DoxyCodeLine{00184     \textcolor{keywordflow}{if} ((rs\_long\_t)len > req) \{}
\DoxyCodeLine{00185         rs\_warn(\textcolor{stringliteral}{"{}copy\_cb() returned more than the requested length"{}});}
\DoxyCodeLine{00186         len = (size\_t)req;}
\DoxyCodeLine{00187     \}}
\DoxyCodeLine{00188     \textcolor{comment}{/* copy back to out buffer only if the callback has used its own buffer */}}
\DoxyCodeLine{00189     \textcolor{keywordflow}{if} (ptr != buffs-\/>next\_out)}
\DoxyCodeLine{00190         memcpy(buffs-\/>next\_out, ptr, len);}
\DoxyCodeLine{00191     \textcolor{comment}{/* Update buffs and copy for copied data. */}}
\DoxyCodeLine{00192     buffs-\/>next\_out += len;}
\DoxyCodeLine{00193     buffs-\/>avail\_out -\/= len;}
\DoxyCodeLine{00194     job-\/>basis\_pos += (rs\_long\_t)len;}
\DoxyCodeLine{00195     job-\/>basis\_len -\/= (rs\_long\_t)len;}
\DoxyCodeLine{00196     \textcolor{keywordflow}{if} (!job-\/>basis\_len) \{}
\DoxyCodeLine{00197         \textcolor{comment}{/* Nothing left to copy, we are done! */}}
\DoxyCodeLine{00198         job-\/>statefn = rs\_patch\_s\_cmdbyte;}
\DoxyCodeLine{00199     \}}
\DoxyCodeLine{00200     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00201 \}}
\DoxyCodeLine{00202 \textcolor{comment}{}}
\DoxyCodeLine{00203 \textcolor{comment}{/** Called while we're trying to read the header of the patch. */}}
\DoxyCodeLine{00204 \textcolor{keyword}{static} rs\_result rs\_patch\_s\_header(rs\_job\_t *job)}
\DoxyCodeLine{00205 \{}
\DoxyCodeLine{00206     \textcolor{keywordtype}{int} v;}
\DoxyCodeLine{00207     rs\_result result;}
\DoxyCodeLine{00208 }
\DoxyCodeLine{00209     \textcolor{keywordflow}{if} ((result = rs\_suck\_n4(job, \&v)) != RS\_DONE)}
\DoxyCodeLine{00210         \textcolor{keywordflow}{return} result;}
\DoxyCodeLine{00211     \textcolor{keywordflow}{if} (v != RS\_DELTA\_MAGIC) \{}
\DoxyCodeLine{00212         rs\_error(\textcolor{stringliteral}{"{}got magic number \%\#x rather than expected value \%\#x"{}}, v,}
\DoxyCodeLine{00213                  RS\_DELTA\_MAGIC);}
\DoxyCodeLine{00214         \textcolor{keywordflow}{return} RS\_BAD\_MAGIC;}
\DoxyCodeLine{00215     \} \textcolor{keywordflow}{else}}
\DoxyCodeLine{00216         rs\_trace(\textcolor{stringliteral}{"{}got patch magic \%\#x"{}}, v);}
\DoxyCodeLine{00217     job-\/>statefn = rs\_patch\_s\_cmdbyte;}
\DoxyCodeLine{00218     \textcolor{keywordflow}{return} RS\_RUNNING;}
\DoxyCodeLine{00219 \}}
\DoxyCodeLine{00220 }
\DoxyCodeLine{00221 rs\_job\_t *rs\_patch\_begin(rs\_copy\_cb * copy\_cb, \textcolor{keywordtype}{void} *copy\_arg)}
\DoxyCodeLine{00222 \{}
\DoxyCodeLine{00223     rs\_job\_t *job = rs\_job\_new(\textcolor{stringliteral}{"{}patch"{}}, rs\_patch\_s\_header);}
\DoxyCodeLine{00224 }
\DoxyCodeLine{00225     job-\/>copy\_cb = copy\_cb;}
\DoxyCodeLine{00226     job-\/>copy\_arg = copy\_arg;}
\DoxyCodeLine{00227     rs\_mdfour\_begin(\&job-\/>output\_md4);}
\DoxyCodeLine{00228     \textcolor{keywordflow}{return} job;}
\DoxyCodeLine{00229 \}}

\end{DoxyCode}
