anchor.diff:                              error
                       end
               end
  -    end.
  -
  -do_net_copy_bytes(FH, Sock) ->
  -    case file:read(FH, 1024*1024) of
  -        {ok, Bin} ->
  -            ok = gen_tcp:send(Sock, Bin),
  -            do_net_copy_bytes(FH, Sock);
  -        eof ->
  -            ok
  -    end.
  -
  -do_net_server_delete_migration_only(Sock, File, DataDir) ->
  -    case sanitize_file_string(File) of
  -        ok ->
  -            do_net_server_delete_migration_only2(Sock, File, DataDir);
  -        _ ->
  -            ok = gen_tcp:send(Sock, <<"ERROR BAD-ARG\n">>)
  -    end.
  -
  -do_net_server_delete_migration_only2(Sock, File, DataDir) ->
  -    {_, Path} = machi_util:make_data_filename(DataDir, File),
  -    case file:delete(Path) of
  -        ok ->
  -            ok = gen_tcp:send(Sock, "OK\n");
  -        {error, enoent} ->
  -            ok = gen_tcp:send(Sock, "ERROR NO-SUCH-FILE\n");
  -        _ ->
  -            ok = gen_tcp:send(Sock, "ERROR\n")
  -    end.
  -
  -do_net_server_truncate_hackityhack(Sock, File, DataDir) ->
  -    case sanitize_file_string(File) of
  -        ok ->
  -            do_net_server_truncate_hackityhack2(Sock, File, DataDir);
  -        _ ->
  -            ok = gen_tcp:send(Sock, <<"ERROR BAD-ARG\n">>)
  -    end.
  -
  -do_net_server_truncate_hackityhack2(Sock, File, DataDir) ->
  -    {_, Path} = machi_util:make_data_filename(DataDir, File),
  -    case file:open(Path, [read, write, binary, raw]) of
  -        {ok, FH} ->
  -            try
  -                {ok, ?MINIMUM_OFFSET} = file:position(FH, ?MINIMUM_OFFSET),
  -                ok = file:truncate(FH),
  -                ok = gen_tcp:send(Sock, "OK\n")
  -            after
  -                file:close(FH)
  -            end;
  -        {error, enoent} ->
  -            ok = gen_tcp:send(Sock, "ERROR NO-SUCH-FILE\n");
  -        _ ->
  -            ok = gen_tcp:send(Sock, "ERROR\n")
       end.
   
   write_server_get_pid(Prefix, DataDir, LinkPid) ->
  
positive.code:             ok;
          _ ->
              error
      end.
  
  do_net_server_append2(FluName, Sock, CSumHex, LenHex, ExtraHex, Prefix) ->
      <<Len:32/big>> = machi_util:hexstr_to_bin(LenHex),
      <<Extra:32/big>> = machi_util:hexstr_to_bin(ExtraHex),
      ClientCSum = machi_util:hexstr_to_bin(CSumHex),
      ok = inet:setopts(Sock, [{packet, raw}]),
      {ok, Chunk} = gen_tcp:recv(Sock, Len, 60*1000),
      try
          CSum = case ClientCSum of
                     <<?CSUM_TAG_NONE:8, _/binary>> ->
                         %% TODO: If the client was foolish enough to use
                         %% this type of non-checksum, then the client gets
                         %% what it deserves wrt data integrity, alas.  In
                         %% the client-side Chain Replication method, each
                         %% server will calculated this independently, which
                         %% isn't exactly what ought to happen for best data
                         %% integrity checking.  In server-side CR, the csum
                         %% should be calculated by the head and passed down
                         %% the chain together with the value.
                         CS = machi_util:checksum_chunk(Chunk),
                         machi_util:make_tagged_csum(server_sha, CS);
                     <<?CSUM_TAG_CLIENT_SHA:8, ClientCS/binary>> ->
                         CS = machi_util:checksum_chunk(Chunk),
                         if CS == ClientCS ->
                                 ClientCSum;
                            true ->
                                 throw({bad_csum, CS})
                         end;
                     _ ->
                         ClientCSum
                 end,
          FluName ! {seq_append, self(), Prefix, Chunk, CSum, Extra}
      catch
          throw:{bad_csum, _CS} ->
              ok = gen_tcp:send(Sock, <<"ERROR BAD-CHECKSUM\n">>),
              exit(normal);
          error:badarg ->
              error_logger:error_msg("Message send to ~p gave badarg, make certain server is running with correct registered name\n", [?MODULE])
      end,
      receive
          {assignment, Offset, File} ->
              OffsetHex = machi_util:bin_to_hexstr(<<Offset:64/big>>),
              Out = io_lib:format("OK ~s ~s ~s\n", [CSumHex, OffsetHex, File]),
              ok = gen_tcp:send(Sock, Out);
          wedged ->
              ok = gen_tcp:send(Sock, <<"ERROR WEDGED\n">>)
      after 10*1000 ->
              ok = gen_tcp:send(Sock, "TIMEOUT\n")
      end.
  
  do_wedge_status(FluName, Sock) ->
      FluName ! {wedge_status, self()},
      Reply = receive
                  {wedge_status_reply, Bool, EpochId} ->
                      BoolHex = if Bool == false -> <<"00">>;
                                   Bool == true  -> <<"01">>
                                end,
                      case EpochId of
                          undefined ->
                              EpochHex = machi_util:int_to_hexstr(0, 32),
                              CSumHex = machi_util:bin_to_hexstr(<<0:(20*8)/big>>);
                          {Epoch, EpochCSum} ->
                              EpochHex = machi_util:int_to_hexstr(Epoch, 32),
                              CSumHex = machi_util:bin_to_hexstr(EpochCSum)
                      end,
                      [<<"OK ">>, BoolHex, 32, EpochHex, 32, CSumHex, 10]
              after 30*1000 ->
                      <<"give_it_up\n">>
              end,
      ok = gen_tcp:send(Sock, Reply).
  
  
  do_net_server_readwrite_common(Sock, OffsetHex, LenHex, FileBin, DataDir,
                                 FileOpts, DoItFun,
                                 EpochID, Wedged_p, CurrentEpochId) ->
      case {Wedged_p, sanitize_file_string(FileBin)} of
          {false, ok} ->
              do_net_server_readwrite_common2(Sock, OffsetHex, LenHex, FileBin,
                                              DataDir, FileOpts, DoItFun,
                                              EpochID, Wedged_p, CurrentEpochId);
          {true, _} ->
              ok = gen_tcp:send(Sock, <<"ERROR WEDGED\n">>);
          {_, __} ->
              ok = gen_tcp:send(Sock, <<"ERROR BAD-ARG\n">>)
      end.
  
  do_net_server_readwrite_common2(Sock, OffsetHex, LenHex, FileBin, DataDir,
                                  FileOpts, DoItFun,
                                  EpochID, Wedged_p, CurrentEpochId) ->
      NoSuchFileFun = fun(Sck) ->
                              ok = gen_tcp:send(Sck, <<"ERROR NO-SUCH-FILE\n">>)
                      end,
      BadIoFun = fun(Sck) ->
                         ok = gen_tcp:send(Sck, <<"ERROR BAD-IO\n">>)
                 end,
      do_net_server_readwrite_common2(Sock, OffsetHex, LenHex, FileBin, DataDir,
                                      FileOpts, DoItFun,
                                      EpochID, Wedged_p, CurrentEpochId,
                                      NoSuchFileFun, BadIoFun).
  
  do_net_server_readwrite_common2(Sock, OffsetHex, LenHex, FileBin, DataDir,
                                  FileOpts, DoItFun,
                                  EpochID, Wedged_p, CurrentEpochId,
                                  NoSuchFileFun, BadIoFun) ->
      <<Offset:64/big>> = machi_util:hexstr_to_bin(OffsetHex),
      <<Len:32/big>> = machi_util:hexstr_to_bin(LenHex),
      {_, Path} = machi_util:make_data_filename(DataDir, FileBin),
      OptsHasWrite = lists:member(write, FileOpts),
      OptsHasRead = lists:member(read, FileOpts),
      case file:open(Path, FileOpts) of
          {ok, FH} ->
              try
                  DoItFun(FH, Offset, Len)
              catch
                  throw:{bad_csum, _CS} ->
                      ok = gen_tcp:send(Sock, <<"ERROR BAD-CHECKSUM\n">>)
              after
                  file:close(FH)
              end;
          {error, enoent} when OptsHasWrite ->
              do_net_server_readwrite_common(
                Sock, OffsetHex, LenHex, FileBin, DataDir,
                FileOpts, DoItFun,
                EpochID, Wedged_p, CurrentEpochId);
          {error, enoent} when OptsHasRead ->
              ok = NoSuchFileFun(Sock);
          _Else ->
              ok = BadIoFun(Sock)
      end.
  
  
  perhaps_do_net_server_ec_read(Sock, FH) ->
      case file:pread(FH, 0, ?MINIMUM_OFFSET) of
          {ok, Bin} when byte_size(Bin) == ?MINIMUM_OFFSET ->
              decode_and_reply_net_server_ec_read(Sock, Bin);
          {ok, _AnythingElse} ->
              ok = gen_tcp:send(Sock, "ERROR PARTIAL-READ2\n");
          _AnythingElse ->
              ok = gen_tcp:send(Sock, "ERROR BAD-PREAD\n")
      end.
  
  decode_and_reply_net_server_ec_read(Sock, <<"a ", Rest/binary>>) ->
      decode_and_reply_net_server_ec_read_version_a(Sock, Rest);
  decode_and_reply_net_server_ec_read(Sock, <<0:8, _/binary>>) ->
      ok = gen_tcp:send(Sock, <<"ERROR NOT-ERASURE\n">>).
  
  decode_and_reply_net_server_ec_read_version_a(Sock, Rest) ->
      %% <<BodyLenHex:4/binary, " ", StripeWidthHex:16/binary, " ",
      %%   OrigFileLenHex:16/binary, " ", _/binary>> = Rest,
      HdrLen = 80 - 2 - 4 - 1,
      <<BodyLenHex:4/binary, " ", Hdr:HdrLen/binary, Rest2/binary>> = Rest,
      <<BodyLen:16/big>> = machi_util:hexstr_to_bin(BodyLenHex),
      <<Body:BodyLen/binary, _/binary>> = Rest2,
      ok = gen_tcp:send(Sock, ["ERASURE ", BodyLenHex, " ", Hdr, Body]).
  
  do_net_server_checksum_listing(Sock, File, DataDir, S) ->
      {Wedged_p, _CurrentEpochId} = ets:lookup_element(S#state.etstab, epoch, 2),
      case {Wedged_p, sanitize_file_string(File)} of
          {true, _} ->
              ok = gen_tcp:send(Sock, <<"ERROR WEDGED\n">>);
          {false, ok} ->
              do_net_server_checksum_listing2(Sock, File, DataDir);
          _ ->
              ok = gen_tcp:send(Sock, <<"ERROR BAD-ARG\n">>)
      end.
  
  do_net_server_checksum_listing2(Sock, File, DataDir) ->
      ok = sync_checksum_file(File),
  
      CSumPath = machi_util:make_checksum_filename(DataDir, File),
      case file:open(CSumPath, [read, raw, binary]) of
          {ok, FH} ->
              {ok, FI} = file:read_file_info(CSumPath),
              Len = FI#file_info.size,
              LenHex = list_to_binary(machi_util:bin_to_hexstr(<<Len:64/big>>)),
              %% Client has option of line-by-line with "." terminator,
              %% or using the offset in the OK message to slurp things
              %% down by exact byte size.
              ok = gen_tcp:send(Sock, [<<"OK ">>, LenHex, <<"\n">>]),
              do_net_copy_bytes(FH, Sock),
              ok = file:close(FH),
              ok = gen_tcp:send(Sock, ".\n");
          {error, enoent} ->
              ok = gen_tcp:send(Sock, "ERROR NO-SUCH-FILE\n");
          _ ->
              ok = gen_tcp:send(Sock, "ERROR\n")
      end.
  
  sync_checksum_file(File) ->
  
negative.code:                                 [Prefix, self(), FileNum, Offset]),
              exit(normal)
      end.
  
  make_listener_regname(BaseName) ->
      list_to_atom(atom_to_list(BaseName) ++ "_listener").
  