+ #
+ $self -> {check_success} = $self -> check_cgi;
+
+ return;
+}
+
+### sub load_main_file #########################################################
+#
+# load and parse the forum main file
+#
+# Return: Success (true/false)
+#
+sub load_main_file {
+ my $self = shift;
+ my $lock_stat;
+
+ unless ($lock_stat = write_lock_file ($self ->{forum_file_name})) {
+ if ($lock_stat == 0) {
+ # occupied or no w-bit set for the directory..., hmmm
+ #
+ violent_unlock_file ($self -> {forum_file_name});
+ $self -> {error} = {
+ spec => 'occupied',
+ type => 'fatal'
+ };
+ return;
+ }
+ else {
+ # master lock is set
+ #
+ $self -> {error} = {
+ spec => 'master_lock',
+ type => 'fatal'
+ };
+ return;
+ }
+ }
+ else {
+ $self -> {forum} -> {flocked} = 1;
+ ( $self -> {forum} -> {threads},
+ $self -> {forum} -> {last_thread},
+ $self -> {forum} -> {last_message},
+ undef,
+ $self -> {forum} -> {unids}
+ ) = get_all_threads ($self -> {forum_file_name}, KEEP_DELETED);
+ }
+
+ # ok, looks good
+ 1;
+}
+
+### sub check_reply_dupe #######################################################
+#
+# check whether a reply is legal
+# (followup posting must exists)
+#
+# check whether this form request is a dupe
+# (unique id already exists)
+#
+# Return: Status Code (Bool)
+#
+sub check_reply_dupe {
+ my $self = shift;
+
+ # return true unless it's not a reply
+ #
+ return 1 unless (
+ $self -> {response} -> {reply}
+ and $self -> {response} -> {new}
+ );
+
+ my %unids;
+
+ if ($self -> {response} -> {reply}) {
+
+ my ($threads, $ftid, $fmid, $i, %msg, %unids) = (
+ $self -> {forum} -> {threads},
+ $self -> {fup_tid},
+ $self -> {fup_mid}
+ );
+
+ # thread doesn't exist
+ #
+ unless (exists($threads -> {$ftid})) {
+ $self -> {error} = {
+ spec => 'no_reply',
+ type => 'fatal'
+ };
+ return;
+ }
+
+ # build a reverse lookup hash (mid => number in array)
+ # and ignore invisible messages
+ # (users can't reply to "deleted" msg)
+ #
+ for ($i=0; $i < @{$threads -> {$ftid}}; $i++) {
+
+ if ($threads -> {$ftid} -> [$i] -> {deleted}) {
+ $i+=$threads -> {$ftid} -> [$i] -> {answers};
+ }
+ else {
+ $msg{$threads -> {$ftid} -> [$i] -> {mid}}=$i;
+ }
+ }
+
+ # message doesn't exist
+ #
+ unless (exists($msg{$fmid})) {
+ $self -> {error} = {
+ spec => 'no_reply',
+ type => 'fatal'
+ };
+ return;
+ }
+
+ # build a unique id lookup hash
+ # use the unids of parent message's kids
+ #
+ %unids = map {$_ => 1} @{$threads -> {$ftid} -> [$msg{$fmid}] -> {unids}};
+ }
+ else {
+ # build a unique id lookup hash, too
+ # but use only the level-zero-messages
+ #
+ %unids = map {$_ => 1} @{$self -> {unids}};
+ }
+
+ # now check on dupe
+ #
+ if (exists ($unids{
+ $self -> {cgi_object} -> param (
+ $self -> {conf} -> {form_data} -> {uniqueID} -> {name})})) {
+ $self -> {error} = {
+ spec => 'dupe',
+ type => 'fatal'
+ };
+ return;
+ }
+
+ # ok, looks fine
+ 1;