This file is indexed.

/usr/share/doc/ejabberd-mod-mam-mnesia/import-mam-archives is in ejabberd-contrib 0.2018.01.12~dfsg0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
#!/usr/bin/env escript
%%! -sname import@localhost

% NOTE: If the node name of your server is *not* 'ejabberd@localhost' (see the
% "ejabberdctl status" output), you must change the @localhost part of the node
% names above and below.

-define(NODE, 'ejabberd@localhost').

% Copyright (c) 2016 Holger Weiss <holger@zedat.fu-berlin.de>.
%
% This program is free software; you can redistribute it and/or modify it under
% the terms of the GNU General Public License as published by the Free Software
% Foundation; either version 2 of the License, or (at your option) any later
% version.
%
% This program is distributed in the hope that it will be useful, but WITHOUT
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
% FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
% details.
%
% You should have received a copy of the GNU General Public License along with
% this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
% Street, Fifth Floor, Boston, MA 02110-1301 USA.

-record(archive_msg, {us, id, timestamp, peer, bare_peer, packet, nick, type}).
-record(mam_msg, {key, time, route, from, to, stanza}).

usage(IoDevice, ExitStatus) ->
    ok = io:put_chars(IoDevice, "Usage: import-mam-archives [days]"),
    ok = io:nl(IoDevice),
    halt(ExitStatus).

get_timestamp() ->
    calendar:datetime_to_gregorian_seconds(calendar:universal_time()).

import(MinTS) ->
    TabDef = [{disc_only_copies, [?NODE]},
	      {type, bag},
	      {attributes, record_info(fields, archive_msg)}],
    rpc:call(?NODE, mnesia, create_table, [archive_msg, TabDef]),

    ImportMsg = fun(#mam_msg{key = {{U, S}, ID},
			     time = TS,
			     route = Direction,
			     from = {FromU, FromS, FromR},
			     to = {ToU, ToS, ToR},
			     stanza = Msg},
		    {ok, N}) when MinTS =:= undefined;
				  TS > MinTS ->
			{PeerU, PeerS, PeerR} =
			    case Direction of
				incoming -> {FromU, FromS, FromR};
				outgoing -> {ToU, ToS, ToR}
			    end,
			Record = #archive_msg{us = {U, S},
					      id = integer_to_binary(ID),
					      timestamp = TS,
					      peer = {PeerU, PeerS, PeerR},
					      bare_peer = {PeerU, PeerS, <<>>},
					      type = chat,
					      nick = <<>>,
					      packet = Msg},
			case N rem 100 of
			    0 -> io:put_chars(".");
			    _ -> ok
			end,
			{mnesia:write(Record), N + 1};
		   (#mam_msg{}, {ok, N}) ->
			{ok, N}
		end,
    ImportTab = fun() ->
			mnesia:foldl(ImportMsg, {ok, 0}, mam_msg)
		end,

    Start = get_timestamp(),
    io:put_chars("Please wait "),
    {ok, N} = rpc:call(?NODE, mnesia, activity,
		       [sync_dirty, ImportTab, [], mnesia_frag]),
    {atomic, ok} = rpc:call(?NODE, mnesia, delete_table, [mam_msg]),
    {atomic, ok} = rpc:call(?NODE, mnesia, delete_table, [mam_meta]),
    End = get_timestamp(),

    io:fwrite("~nImported ~B messages in ~.1f minutes.~n",
	      [N, (End - Start) / 60]).

main(["-h"]) ->
    usage(standard_io, 0);
main([]) ->
    import(undefined);
main([Days]) ->
    Secs = try
	       D = list_to_integer(Days),
	       true = D > 0,
	       true = D < 10000,
	       D * 86400
	   catch
	       _:_ -> usage(standard_error, 2)
	   end,
    {MS, S, US} = os:timestamp(),
    CurS = MS * 1000000 + S,
    MinS = CurS - Secs,
    import({MinS div 1000000, MinS rem 1000000, US});
main(_Junk) ->
    usage(standard_error, 2).