bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: CVS/Template files ... requesting opinion/clue


From: Derek Robert Price
Subject: Re: CVS/Template files ... requesting opinion/clue
Date: Fri, 07 Mar 2003 11:56:25 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.2) Gecko/20030208 Netscape/7.02

Mark D. Baushke wrote:

Hi Folks,

This patch is a bit different than the last one. I have added some hacks
to the top of the sanity.sh that let me test against other clients and
servers ... should this kind of change be retained? It is useful to test
to make sure that we have retained some forward compatibility where
possible.


Sounds good to me, but please document the new variables in TESTS.

Two things I'll probably get around ot after your commit if you don't feel like doing it before: -s <serverapp> should probably imply -r, and search/replacing testcvs with clientcvs. It looks like one less level of misdirection wouldn't hurt.

After some additional testing with old clients, I ended up choosing to
write a zero length CVS/Template file if the Clear-template response was
not available on the client and the sanity.sh tests reflect this shift.

I still don't know the right way to get the CVS/Template file updated in
place when the user commits a change to rcsinfo or any other files that
might have been included by rcsinfo during a database rebuild.


I don't think there's an easy way to do this without an update. As long as it works in client/server mode, I'm all for this being committed to the trunk.

The baseline bug that has been biting folks in my company are:

 -> a new directory added with 'cvs add' does not have a CVS/Template
    file and leads to problems with our verifymsg script.

 -> some engineers have really old trees that they continue to update
    and the CVS/Template files are not up-to-date. This can give them
    problems when they try to commit changes if they miss some of the
    needed keywords for our verifymsg script. A 'cvs update' is a small
    price to pay to get the right CVS/Template in the sandbox updated.

The patch below solves this problem for me. I just don't know if it is
'good enough' for the general cvshome.org ccvs source base.

In other questions, there is very little standardization in how
sanity.sh tests are named with regard to remote versus local processing.
Is there a document I am missing that describes what should be done?
Also, "${testcvs} ..." vs "$testcvs ..." and the lack of consisten $keep
exit points makes things more interesting. If you have any pointers, I'd
love to hear about them.


The lack of consistent $keep exit points is because $keep is a fairly recent addition to the suite and nobody took the time to revamp the whole script. The rule I've been using is that I add $keep anytime I work on a test if it isn't there already, to any new test, and any time I need it and it isn't there.

If you're feeling motivated enough to put $keep exit points in all the tests, by all means feel free. :)

As for a remote naming scheme, I don't think it's ever been codified. The method I stumbled across in some of the tests, and the one I've been using, is that if it has a parallel local test, for example where the exact same CVS command is used but the output can differ, use the same test name but append "r". For example:

          if $remote; then
            dotest unedit-without-baserev-6r "${testcvs} -q update" "U m"
          else
            dotest unedit-without-baserev-6 "${testcvs} -q update" \
"${PROG} update: warning: m was lost
U m"
          fi


I only started doing that recently, so there may not be many examples of that. I'm not sure what to do in the cases where there are a string of remote tests with no parallel local tests. Perhaps just always append an "r" after the test name anyhow? Feel free to use that or discuss another standard. Perhaps we should document that and $keep in TESTS?

Suggestions welcome.

        Later,
        -- Mark

Index: src/ChangeLog
===================================================================
RCS file: /cvs/ccvs/src/ChangeLog,v
retrieving revision 1.2373
diff -u -p -r1.2373 ChangeLog
--- ./src/ChangeLog     6 Mar 2003 17:55:26 -0000       1.2373
+++ ./src/ChangeLog     7 Mar 2003 08:29:12 -0000
@@ -1,3 +1,29 @@
+2003-03-06  Mark D. Baushke  <mdb@cvshome.org>
+
+       * entries.c (WriteTemplate): New function to control updates to
+       the CVS/Template file or its removal.
+       * create_adm.c (Create_Admin): Use the new WriteTemplate function.
+       * add.c (add_directory): Add a WriteTemplate() call
+       when a new directory is added to the repository.
+       * commit.c (commit_filesdoneproc): Ensure that the CVS/Template is
+       updated at the end of a commit -- mostly to remove it if it is not
+       relevant.
+       (commit_dirleaveproc): Ensure that the CVS/Template gets updated
+       when the directory is left.
+       * update.c (update_dirent_proc): Update CVS/Template file.
+       * server.c (server_clear_template): New protocol response to
+       remove existing CVS/Template files.
+       * client.c (clear_template): New function to remove or truncate a
+       CVS/Template file.
+       (handle_clear_template): New function. Handle Clear-template
+       protocol response message.
+       (save_prog): Add new Clear-template response line.
+       * sanity.sh (template): Test the CVS/Template creation with
+       the remote protocol. Nothing gets created locally.
+       (multiroot2): Fix for minor changes to trace output.
+       (getopts): Allow tests to be run with specified client and server
+       cvs commands to allow for interoperatbility testing.
+       
2003-03-06  Larry Jones  <lawrence.jones@eds.com>

        * sanity.sh (branches3-4): Set and export CVS_LOCAL_BRANCH_NUM
Index: src/add.c
===================================================================
RCS file: /cvs/ccvs/src/add.c,v
retrieving revision 1.81
diff -u -p -r1.81 add.c
--- ./src/add.c 7 Feb 2003 19:53:30 -0000       1.81
+++ ./src/add.c 7 Mar 2003 08:29:12 -0000
@@ -809,6 +809,8 @@ add_directory (finfo)
    if (!server_active)
#endif
        Create_Admin (".", finfo->fullname, rcsdir, tag, date, nonbranch, 0, 1);
+    WriteTemplate (finfo->fullname, 1, rcsdir);
+
    if (tag)
        free (tag);
    if (date)
Index: src/client.c
===================================================================
RCS file: /cvs/ccvs/src/client.c,v
retrieving revision 1.320
diff -u -p -r1.320 client.c
--- ./src/client.c      6 Feb 2003 17:33:50 -0000       1.320
+++ ./src/client.c      7 Mar 2003 08:29:12 -0000
@@ -123,6 +123,7 @@ static void handle_set_static_directory static void handle_clear_static_directory PROTO((char *, int));
static void handle_set_sticky PROTO((char *, int));
static void handle_clear_sticky PROTO((char *, int));
+static void handle_clear_template PROTO((char *, int));
static void handle_set_checkin_prog PROTO((char *, int));
static void handle_set_update_prog PROTO((char *, int));
static void handle_module_expansion PROTO((char *, int));
@@ -2547,6 +2548,26 @@ handle_template (pathname, len)
    call_in_directory (pathname, template, NULL);
}

+static void
+clear_template (data, ent_list, short_pathname, filename)
+    char *data;
+    List *ent_list;
+    char *short_pathname;
+    char *filename;
+{
+    if (unlink_file (CVSADM_TEMPLATE) < 0 && ! existence_error (errno))
+       error (1, errno, "cannot remove %s", CVSADM_TEMPLATE);
+}
+
+static void
+handle_clear_template (pathname, len)
+    char *pathname;
+    int len;
+{
+    call_in_directory (pathname, clear_template, NULL);
+}
+
+

struct save_prog {
    char *name;
@@ -3408,6 +3429,8 @@ struct response responses[] =
    RSP_LINE("Clear-sticky", handle_clear_sticky, response_type_normal,
       rs_optional),
    RSP_LINE("Template", handle_template, response_type_normal,
+       rs_optional),
+    RSP_LINE("Clear-template", handle_clear_template, response_type_normal,
       rs_optional),
    RSP_LINE("Set-checkin-prog", handle_set_checkin_prog, response_type_normal,
       rs_optional),
Index: src/commit.c
===================================================================
RCS file: /cvs/ccvs/src/commit.c,v
retrieving revision 1.188
diff -u -p -r1.188 commit.c
--- ./src/commit.c      7 Feb 2003 21:34:03 -0000       1.188
+++ ./src/commit.c      7 Mar 2003 08:29:12 -0000
@@ -1468,6 +1468,7 @@ commit_filesdoneproc (callerdat, err, re
            cvs_output (": Rebuilding administrative file database\n", 0);
            mkmodules (admin_dir);
            free (admin_dir);
+           WriteTemplate (".", 1, repository);
        }
    }

@@ -1589,6 +1590,12 @@ commit_dirleaveproc (callerdat, dir, err
        char *repos = Name_Repository (NULL, update_dir);
        WriteTag (NULL, write_dirtag, NULL, write_dirnonbranch,
                  update_dir, repos);
+       free (repos);
+    }
+    if (err == 0)
+    {
+       char *repos = Name_Repository (NULL, update_dir);
+       WriteTemplate (update_dir, 1, repos);
        free (repos);
    }

Index: src/create_adm.c
===================================================================
RCS file: /cvs/ccvs/src/create_adm.c,v
retrieving revision 1.38
diff -u -p -r1.38 create_adm.c
--- ./src/create_adm.c  3 Feb 2003 17:53:23 -0000       1.38
+++ ./src/create_adm.c  7 Mar 2003 08:29:12 -0000
@@ -159,14 +159,10 @@ Create_Admin (dir, update_dir, repositor
    /* Create a new CVS/Tag file */
    WriteTag (dir, tag, date, nonbranch, update_dir, repository);

-#ifdef SERVER_SUPPORT
-    if (server_active && dotemplate)
-    {
-       server_template (update_dir, repository);
-    }
+    /* Create a new CVS/Template file */
+    WriteTemplate (update_dir, dotemplate, repository);

    TRACE ( 1, "Create_Admin" );
-#endif

    free (reposcopy);
    free (tmp);
Index: src/entries.c
===================================================================
RCS file: /cvs/ccvs/src/entries.c,v
retrieving revision 1.47
diff -u -p -r1.47 entries.c
--- ./src/entries.c     3 Feb 2003 17:53:23 -0000       1.47
+++ ./src/entries.c     7 Mar 2003 08:29:12 -0000
@@ -628,6 +628,33 @@ AddEntryNode (list, entdata)
}

/*
+ * Write out the CVS/Template file.
+ */
+void
+WriteTemplate (update_dir, xdotemplate, repository)
+    char *update_dir;
+    int xdotemplate;
+    char *repository;
+{
+    if (noexec)
+       return;
+
+#ifdef SERVER_SUPPORT
+    if (server_active && xdotemplate)
+    {
+       /* Clear the CVS/Template if supported to allow for the case
+        * where the rcsinfo file no longer has an entry for this
+        * directory.
+        */
+       server_clear_template (update_dir, repository);
+       server_template (update_dir, repository);
+    }
+
+    TRACE (1, "Write_Template (%s, %s)", update_dir, repository);
+#endif
+}
+
+/*
 * Write out/Clear the CVS/Tag file.
 */
void
Index: src/sanity.sh
===================================================================
RCS file: /cvs/ccvs/src/sanity.sh,v
retrieving revision 1.766
diff -u -p -r1.766 sanity.sh
--- ./src/sanity.sh     6 Mar 2003 17:55:26 -0000       1.766
+++ ./src/sanity.sh     7 Mar 2003 08:29:12 -0000
@@ -55,7 +55,9 @@ export LC_ALL
unset fromtest
keep=false
remote=false
-while getopts f:kr option ; do
+clientcvs=false
+servercvs=false
+while getopts f:krc:s: option ; do
    case "$option" in
        f)
            fromtest="$OPTARG"
@@ -70,6 +72,12 @@ while getopts f:kr option ; do
        r)
            remote=:
            ;;
+        c)
+            clientcvs="$OPTARG"
+           ;;
+        s)
+            servercvs="$OPTARG"
+           ;;
        \?)
            exit_usage
            ;;
@@ -89,15 +97,19 @@ case $1 in
  exit_usage
  ;;
/*)
-  testcvs=$1
+  cmdargcvs=$1
  ;;
*)
-  testcvs=`pwd`/$1
+  cmdargcvs=`pwd`/$1
  ;;
esac
shift

-
+if [ "$clientcvs" != "false" ]; then
+    testcvs="${clientcvs}"
+else
+    testcvs="${cmdargcvs}"
+fi

###
### GUTS
@@ -716,7 +728,7 @@ if test x"$*" = x; then
        # Multiple root directories and low-level protocol tests.
        tests="${tests} multiroot multiroot2 multiroot3 multiroot4"
        tests="${tests} rmroot reposmv pserver server server2 client"
-       tests="${tests} fork commit-d"
+       tests="${tests} fork commit-d template"
else
        tests="$*"
fi
@@ -1573,7 +1585,11 @@ if $remote; then
        # :ext:, you can run the tests that way.  There is a known
        # difference in modes-15 (see comments there).
        CVSROOT=:fork:${CVSROOT_DIRNAME} ; export CVSROOT
-       CVS_SERVER=${testcvs}; export CVS_SERVER
+       if [ $servercvs = "false" ]; then
+           CVS_SERVER=${cmdargcvs}; export CVS_SERVER
+        else
+           CVS_SERVER=${servercvs}; export CVS_SERVER
+        fi
else
        CVSROOT=${CVSROOT_DIRNAME} ; export CVSROOT
fi
@@ -23312,16 +23328,20 @@ ${PROG} server: Updating dir1/sdir/ssdir
          if $remote; then :; else
            dotest multiroot2-9a "${testcvs} -t update" \
" *-> main loop with CVSROOT=${TESTDIR}/root1
+ *-> Write_Template (\., ${TESTDIR}/root1)
${PROG} update: Updating \.
 *-> Reader_Lock(${TESTDIR}/root1)
 *-> Lock_Cleanup()
+ *-> Write_Template (dir1, ${TESTDIR}/root1/dir1)
${PROG} update: Updating dir1
 *-> Reader_Lock(${TESTDIR}/root1/dir1)
 *-> Lock_Cleanup()
 *-> main loop with CVSROOT=${TESTDIR}/root2
+ *-> Write_Template (dir1/sdir, ${TESTDIR}/root2/dir1/sdir)
${PROG} update: Updating dir1/sdir
 *-> Reader_Lock(${TESTDIR}/root2/sdir)
 *-> Lock_Cleanup()
+ *-> Write_Template (dir1/sdir/ssdir, ${TESTDIR}/root2/sdir/ssdir)
${PROG} update: Updating dir1/sdir/ssdir
 *-> Reader_Lock(${TESTDIR}/root2/sdir/ssdir)
 *-> Lock_Cleanup()
@@ -24572,6 +24592,182 @@ new revision: 1.2; previous revision: 1.
done"
          cd ../..
          rm -rf 1 cvsroot/c-d-c
+         ;;
+
+       template)
+         # Check that the CVS/Template directory is being
+         # properly created.
+         mkdir -p ${CVSROOT_DIRNAME}/first/subdir
+         mkdir -p ${CVSROOT_DIRNAME}/second
+         mkdir template; cd template
+
+         # check that no CVS/Template is created for an empty rcsinfo
+         # Note: For cvs clients with no Clear-template response, the
+         # CVS/Template file will exist and be zero bytes in length.
+         dotest template-empty-1 "${testcvs} -Q co first" ''
+         dotest template-empty-2 \
+"! test -f first/CVS/Template || ! test -s first/CVS/Template" ''
+         dotest template-empty-3 \
+"! test -f first/subdir/CVS/Template || ! test -s first/subdir/CVS/Template" ''
+         rm -fr first
+
+         # create some template files
+         echo 'CVS: the default template' > ${TESTDIR}/template/temp.def
+         echo 'CVS: the first template' > ${TESTDIR}/template/temp.first
+         echo 'CVS: the subdir template' > ${TESTDIR}/template/temp.subdir
+ + dotest template-rcsinfo-1 "${testcvs} -Q co CVSROOT" ''
+         cd CVSROOT
+         echo "^first/subdir ${TESTDIR}/template/temp.subdir" >>rcsinfo
+         echo "^first ${TESTDIR}/template/temp.first" >>rcsinfo
+         echo DEFAULT ${TESTDIR}/template/temp.def >>rcsinfo
+         dotest template-rcsinfo-2 "${testcvs} -Q ci -m. rcsinfo" \
+"Checking in rcsinfo;
+${CVSROOT_DIRNAME}/CVSROOT/rcsinfo,v  <--  rcsinfo
+new revision: 1\.2; previous revision: 1\.1
+done
+$PROG [a-z]*: Rebuilding administrative file database"
+         # Did the CVSROOT/CVS/Template file get the updated version?
+         # FIXME. This result is wrong!
+         #dotest template-rcsinfo-3 "cmp CVS/Template 
${TESTDIR}/template/temp.def" ''
+         dotest template-rcsinfo-3 \
+"! test -f CVS/Template || ! test -s CVS/Template" ''
+
+         cd ..
+
+         # Now checkout the first and second modules and see
+         # if the proper template has been provided for each
+         dotest template-first "${testcvs} co first second" \
+"$PROG [a-z]*: Updating first
+$PROG [a-z]*: Updating first/subdir
+$PROG [a-z]*: Updating second"
+
+         if $remote; then
+           # When in client/server CVS/Template must exist
+           dotest template-first-r-1 "test -f first/CVS/Template" ''
+           dotest template-first-r-2 "test -f first/subdir/CVS/Template" ''
+           dotest template-first-r-3 "test -f second/CVS/Template" ''
+           # The value of the CVS/Template should be equal to the
+           # file called out in the rcsinfo file.
+           dotest template-first-r-4 \
+"cmp first/CVS/Template ${TESTDIR}/template/temp.first" ''
+           dotest template-first-r-5 \
+"cmp first/subdir/CVS/Template ${TESTDIR}/template/temp.subdir" ''
+           dotest template-first-r-6 \
+"cmp second/CVS/Template ${TESTDIR}/template/temp.def" ''
+          else
+           # When in local mode CVS/Template must NOT exist
+           dotest_fail template-first-1 "test -f first/CVS/Template" ''
+           dotest_fail template-first-2 "test -f first/subdir/CVS/Template" ''
+           dotest_fail template-first-3 "test -f second/CVS/Template" ''
+         fi
+
+         # Next, create a new subdirectory and see if it gets the
+         # correct template or not
+         cd second
+         mkdir otherdir
+         dotest template-add-1 "${testcvs} add otherdir" \
+"Directory ${CVSROOT_DIRNAME}/second/otherdir added to the repository"
+         if $remote; then
+           dotest template-add-2r \
+"cmp otherdir/CVS/Template ${TESTDIR}/template/temp.def" ''
+         else
+           dotest_fail template-add-2 "test -f otherdir/CVS/Template" ''
+         fi
+         cd ..
+
+         # Update the remote template. Then see if doing an
+         # update of a checked out tree will properly update
+         # the CVS/Template files.
+         echo 'CVS: Line two' >> ${TESTDIR}/template/temp.def
+         echo 'CVS: Line two' >> ${TESTDIR}/template/temp.first
+         echo 'CVS: Line two' >> ${TESTDIR}/template/temp.subdir
+         dotest template-second "${testcvs} update first second" \
+"$PROG [a-z]*: Updating first
+$PROG [a-z]*: Updating first/subdir
+$PROG [a-z]*: Updating second
+$PROG [a-z]*: Updating second/otherdir"
+
+         if $remote; then
+           dotest template-second-r-1 \
+"cmp first/CVS/Template ${TESTDIR}/template/temp.first" ''
+           dotest template-second-r-2 \
+"cmp first/subdir/CVS/Template ${TESTDIR}/template/temp.subdir" ''
+           dotest template-second-r-3 \
+"cmp second/CVS/Template ${TESTDIR}/template/temp.def" ''
+           dotest template-second-r-4 \
+"cmp second/otherdir/CVS/Template ${TESTDIR}/template/temp.def" ''
+          else
+           # When in local mode CVS/Template must NOT exist
+           dotest_fail template-second-1 "test -f CVS/Template" ''
+           dotest_fail template-second-2 "test -f subdir/CVS/Template" ''
+           dotest_fail template-second-3 "test -f second/CVS/Template" ''
+           dotest_fail template-second-4 \
+"test -f second/otherdir/CVS/Template" ''
+         fi
+         # Update the remote template with a zero-length template
+         : > ${TESTDIR}/template/temp.def
+         dotest template-third-1 "${testcvs} update second" \
+"${PROG} [a-z]*: Updating second
+${PROG} [a-z]*: Updating second/otherdir"
+
+         if $remote; then
+           dotest_fail template-third-r-2 "test -s second/CVS/Template" ''
+           dotest_fail template-third-r-3 "test -s 
second/otherdir/CVS/Template" ''
+          else
+           dotest_fail template-third-2 "test -f second/CVS/Template" ''
+           dotest_fail template-third-3 \
+"test -f second/otherdir/CVS/Template" ''
+          fi
+
+         cd CVSROOT
+         dotest template-norcsinfo-1 "${testcvs} up" \
+"${PROG} [a-z]*: Updating \."
+         # Did the CVSROOT/CVS/Template file get the updated version?
+         if $remote; then
+           dotest template-norcsinfo-r-2 \
+"cmp CVS/Template ${TESTDIR}/template/temp.def" ''
+          else
+           dotest_fail template-norcsinfo-2 "test -f CVS/Template" ''
+         fi
+
+         : > rcsinfo
+         dotest template-norcsinfo-3 "${testcvs} -Q ci -m. rcsinfo" \
+"Checking in rcsinfo;
+${CVSROOT_DIRNAME}/CVSROOT/rcsinfo,v  <--  rcsinfo
+new revision: 1\.3; previous revision: 1\.2
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+         # Did the CVSROOT/CVS/Template file get the updated version?
+         # FIXME. This result is wrong!
+         #dotest template-norcsinfo-4 "test -f CVS/Template" ''
+         dotest template-norcsinfo-4 \
+"! test -f CVS/Template || ! test -s CVS/Template" ''
+         cd ..
+
+         dotest template-norcsinfo-5 "${testcvs} update first" \
+"${PROG} [a-z]*: Updating first
+${PROG} [a-z]*: Updating first/subdir"
+
+         # Note: For cvs clients with no Clear-template response, the
+         # CVS/Template file will exist and be zero bytes in length.
+         dotest template-norcsinfo-6 \
+"! test -f first/CVS/Template || ! test -s first/CVS/Template" ''
+         dotest template-norcsinfo-7 \
+"! test -f first/subdir/CVS/Template || ! test -s first/subdir/CVS/Template" ''
+
+         if $keep; then
+           echo Keeping ${TESTDIR} and exiting due to --keep
+           exit 0
+         fi
+
+         # cleanup
+         rm -f ${CVS_DIRNAME}/CVSROOT/rcsinfo,v \
+                ${CVS_DIRNAME}/CVSROOT/rcsinfo \
+                ${CVS_DIRNAME}/first ${CVS_DIRNAME}/second
+         dotest template-cleanup-1 "${testcvs} -Q init" ''
+         cd ..
+         rm -rf template
          ;;

        *)
Index: src/server.c
===================================================================
RCS file: /cvs/ccvs/src/server.c,v
retrieving revision 1.287
diff -u -p -r1.287 server.c
--- ./src/server.c      21 Feb 2003 21:44:14 -0000      1.287
+++ ./src/server.c      7 Mar 2003 08:29:12 -0000
@@ -4416,6 +4416,38 @@ template_proc (repository, template)
}

void
+server_clear_template (update_dir, repository)
+    char *update_dir;
+    char *repository;
+{
+    assert (update_dir != NULL);
+
+    if (noexec)
+       return;
+
+    if (!supported_response ("Clear-template") &&
+       !supported_response ("Template"))
+       /* Might want to warn the user that the rcsinfo feature won't work.  */
+       return;
+
+    if (supported_response ("Clear-template"))
+    {
+       buf_output0 (protocol, "Clear-template ");
+       output_dir (update_dir, repository);
+       buf_output0 (protocol, "\n");
+       buf_send_counted (protocol);
+    }
+    else
+    {
+       buf_output0 (protocol, "Template ");
+       output_dir (update_dir, repository);
+       buf_output0 (protocol, "\n");
+       buf_output0 (protocol, "0\n");
+       buf_send_counted (protocol);
+    }
+}
+
+void
server_template (update_dir, repository)
    char *update_dir;
    char *repository;
Index: src/update.c
===================================================================
RCS file: /cvs/ccvs/src/update.c,v
retrieving revision 1.205
diff -u -p -r1.205 update.c
--- ./src/update.c      28 Feb 2003 23:11:21 -0000      1.205
+++ ./src/update.c      7 Mar 2003 08:29:12 -0000
@@ -1025,6 +1025,8 @@ update_dirent_proc (callerdat, dir, repo
            nonbranch = 0;
        }

+       WriteTemplate (update_dir, dotemplate, repository);
+
        /* initialize the ignore list for this directory */
        ignlist = getlist ();
    }

Derek

--
               *8^)

Email: derek@ximbiot.com

Get CVS support at <http://ximbiot.com>!
--
Man who run behind car get exhausted.







reply via email to

[Prev in Thread] Current Thread [Next in Thread]