473,473 Members | 4,204 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

updating deprecated sys_errlist? Simple Question?

Hi there,

First I'll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it's intended to be portable code (it was available as source and
as a DOS binary, but mention was made of UNIX in the readme - I am
compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn't compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better 'updated'.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
extern int errno;

// extern char *sys_errlist[]; // commented out by me
// extern int sys_nerr; // commented out by me

char *errmess;

if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open '%s'!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/

errmess = strerror(errno); // added by me

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
exit(1);
}
return(f);
}

This code compiles just fine, and it also works as intended, but I
assume it will fail much less gracefully if I send a 'bad' file to the
program.

I assume I did the right thing changing the #include directive from
malloc.h to stdlib.h

I realised I needed to find a more modern equivalent of sys_errlist and
sys_nerr, - a web search led me to discover that sys_errlist is
deprecated, and to put together the single line I added.

I also learned that strerror is provided by stdio.h (which was already
#included). All well and good, but I have no clue how to reinstate the
'if' test and make the error handling more robust.

Thanks in advance for any assistance!
Mar 19 '06 #1
10 4372
Brennan Young opined:
Hi there,

First I'll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it's intended to be portable code (it was available as source
and as a DOS binary, but mention was made of UNIX in the readme - I
am compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn't compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better 'updated'.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me
#include <errno.h>
#include <string.h>

You'll need it below...

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
This is ancient style. It's better:

FILE *efopen(char *name, char *mode)
{
FILE *f;
extern int errno;
Now you don't need the line above (errno is declared in errno.h).
// extern char *sys_errlist[]; // commented out by me
// extern int sys_nerr; // commented out by me
This is some ancient, system-specific system of mapping error messages
to error codes. Now you should use `strerr()`.
char *errmess;
You could put:

errno = 0;

as the Standard only specifies that it's set to 0 at program startup,
and library function /may/ set it to positive value (NB, error or no
error!), but never to zero. Here's also the relevant paragraph from
the Standard:

7.5p3
The value of errno is zero at program startup, but is never set
to zero by any library function. The value of errno may be
set to nonzero by a library function call whether or not there
is an error, provided the use of errno is not documented in the
description of the function in this International Standard.
if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open
'%s'!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/
if (errno)
errmess = strerror(errno); // added by me

Is what you want here.

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
exit(1);
}
return(f);
}

This code compiles just fine, and it also works as intended, but I
assume it will fail much less gracefully if I send a 'bad' file to
the program.
It may, or it may not, depending on the implementation. I think
Standard does not guarantee that `strerror()` will return anything
sensible (it just talks of returning a pointer to "a message").
I assume I did the right thing changing the #include directive from
malloc.h to stdlib.h
Yes. You also need <errno.h> and <string.h> for error handling.
I realised I needed to find a more modern equivalent of sys_errlist
and sys_nerr, - a web search led me to discover that sys_errlist is
deprecated, and to put together the single line I added.

I also learned that strerror is provided by stdio.h (which was
already #included).


I think it's only in <string.h>, but may be wrong.

HTH

--
BR, Vladimir

You will pioneer the first Martian colony.

Mar 19 '06 #2
Brennan Young wrote:
Hi there,

First I'll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it's intended to be portable code (it was available as source and
as a DOS binary, but mention was made of UNIX in the readme - I am
compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn't compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better 'updated'.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
extern int errno;

// extern char *sys_errlist[]; // commented out by me
This most likely contains mappings for the error number to the error
text, however without seeing the actual definitions all I can do is
guess. If this is the case, take a look at strerror(). Also perror()
would work just fine here.
// extern int sys_nerr; // commented out by me
There is errno which is provided by errno.h that you can use for this.

char *errmess;

if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open '%s'!\n",name);
Given the above information, this can be changed to:

if((f = fopen(name, mode)) == NULL) {
perror("fopen");

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/
You can leave this out. We are already doing this above with perror().

errmess = strerror(errno); // added by me

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
The above two lines are redundant now as well.
exit(1);
Sloppy. You might want to use EXIT_FAILURE here instead.
}
return(f);
}

This code compiles just fine, and it also works as intended, but I
assume it will fail much less gracefully if I send a 'bad' file to the
program.
Actually no, it won't. It will fail just as gracefully as it did before
you made the changes, the only different is that with your changes it
will not print out an error message upon failure (which could be a Bad
Thing(tm)).

I assume I did the right thing changing the #include directive from
malloc.h to stdlib.h
Yes.

I realised I needed to find a more modern equivalent of sys_errlist and
sys_nerr, - a web search led me to discover that sys_errlist is
deprecated, and to put together the single line I added.
You don't need either one of those.

I also learned that strerror is provided by stdio.h (which was already
#included). All well and good, but I have no clue how to reinstate the
'if' test and make the error handling more robust.
The error handling looks perfectly fine to me. If fopen() returns NULL
then simply call perror("fopen") to see the error message.

Thanks in advance for any assistance!


No problem, hope that gets you pointed in the right direction.

Joe
Mar 19 '06 #3
On 2006-03-19, Joe Estock <je*****@NOSPAMnutextonline.com> wrote:
Brennan Young wrote:
Hi there,

First I'll apologise for my ignorance!

I have been attempting to compile some code that I found on the net.

AFAICT it's intended to be portable code (it was available as source and
as a DOS binary, but mention was made of UNIX in the readme - I am
compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn't compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better 'updated'.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me

//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;
{
FILE *f;
extern int errno;

// extern char *sys_errlist[]; // commented out by me


This most likely contains mappings for the error number to the error
text, however without seeing the actual definitions all I can do is
guess. If this is the case, take a look at strerror(). Also perror()
would work just fine here.
// extern int sys_nerr; // commented out by me


There is errno which is provided by errno.h that you can use for this.


sys_nerr is the total number of entries in sys_errlist, NOT an index.

[well, it can be whatever an implementation wants it to be, but my guess
is more likely to be right than yours]
char *errmess;

if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open '%s'!\n",name);


Given the above information, this can be changed to:

if((f = fopen(name, mode)) == NULL) {
perror("fopen");


I'd have used perror(name) instead.
Mar 19 '06 #4
Vladimir S. Oka wrote:
Brennan Young opined:
Hi there,

First I'll apologise for my ignorance!
Being ignorant is not a problem. It's those who do not recognise their
ignorance that are the problem!
I have been attempting to compile some code that I found on the net.

AFAICT it's intended to be portable code (it was available as source
and as a DOS binary, but mention was made of UNIX in the readme - I
am compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn't compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better 'updated'.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me
Changing it to stdlib.h was correct. However, you should not use //
style comments because they were only added to the C standard in C99 and
C99 is not generally implemented. Also, // style comments don't survive
line wrapping.
#include <errno.h>
#include <string.h>

You'll need it below...
//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;


This is ancient style. It's better:

FILE *efopen(char *name, char *mode)


You should also change any declarations to this style, and ensure that
there is always a declaration (or definition) at some point before a
function is called.
{
FILE *f;
extern int errno;


Now you don't need the line above (errno is declared in errno.h).


It's worse than that. errno is not guaranteed to be an object and on
many systems it is not! It is not that long back that I was dealing with
some old code and it failed to run because errno was explicitly declared
like this instead of errno.h being included. On such systems, declaring
errno like this and including errno.h would be likely to lead to a
compilation error.

<snip good stuff>
if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open
'%s'!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/


if (errno)
errmess = strerror(errno); // added by me

Is what you want here.


You also want:
else
errmess = "Unknown error!";

from the original code. Otherwise errmess is not set to anything if
errno==0.

(void) fprintf(stderr,"************* Reason: %s\n",errmess);
exit(1);
exit(1) is not portable. In fact, under VMS it would be a success code!
exit(EXIT_FAILURE);
}
return(f);
}


<snip>

A final point, since we are so often told we spend all our time
complaining about off topic posts.

The original post by Brennan Young was on topic, showed that he had made
an effort and explained clearly what he wanted to know.

Welcome to the group Brennan. The question may be simple but it is what
we are here for.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 21 '06 #5
On 2006-03-21, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Vladimir S. Oka wrote:
Brennan Young opined:
Hi there,

First I'll apologise for my ignorance!
Being ignorant is not a problem. It's those who do not recognise their
ignorance that are the problem!
I have been attempting to compile some code that I found on the net.

AFAICT it's intended to be portable code (it was available as source
and as a DOS binary, but mention was made of UNIX in the readme - I
am compiling under Mac OS X, fwiw).

It probably once was portable, but apparently uses some obsolete
snippets because it wouldn't compile without some changes.

After searching the web I managed to get the code to compile but it
required that I simplify some error handling which I feel ought to be
better 'updated'.

Here are the relevant bits:
//#include <malloc.h> // commented out by me
#include <stdlib.h> // added by me
Changing it to stdlib.h was correct. However, you should not use //
style comments because they were only added to the C standard in C99 and
C99 is not generally implemented. Also, // style comments don't survive
line wrapping.
#include <errno.h>
#include <string.h>

You'll need it below...
//plenty of unaltered code snipped

FILE *
efopen(name,mode)
char *name;
char *mode;


This is ancient style. It's better:

FILE *efopen(char *name, char *mode)


You should also change any declarations to this style, and ensure that
there is always a declaration (or definition) at some point before a
function is called.
{
FILE *f;
extern int errno;


Now you don't need the line above (errno is declared in errno.h).


It's worse than that. errno is not guaranteed to be an object and on
many systems it is not! It is not that long back that I was dealing with
some old code and it failed to run because errno was explicitly declared
like this instead of errno.h being included. On such systems, declaring
errno like this and including errno.h would be likely to lead to a
compilation error.

<snip good stuff>
if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open
'%s'!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/


if (errno)
errmess = strerror(errno); // added by me

Is what you want here.


You also want:
else
errmess = "Unknown error!";

from the original code. Otherwise errmess is not set to anything if
errno==0.


strerror(0) doesn't return anything? on mine, it returns "Success".

Also, you're misreading it - "Unknown Error!" is set NOT on errno 0, but
on errno that's larger than the largest value for which an error message
is defined [on a typical modern system, strerror would return "Unknown \
Error 500" for that case]
Mar 22 '06 #6
Jordan Abel wrote:
On 2006-03-21, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Vladimir S. Oka wrote:
Brennan Young opined:
<snip>
if ( (f=fopen(name,mode)) == NULL ) {
(void) fprintf(stderr,"*** ERROR *** Cannot open
'%s'!\n",name);

/* // this chunk commented out by me

if ( errno <= sys_nerr )
errmess = sys_errlist[errno];
else
errmess = "Unknown error!";

*/
if (errno)
errmess = strerror(errno); // added by me

Is what you want here. You also want:
else
errmess = "Unknown error!";

from the original code. Otherwise errmess is not set to anything if
errno==0.


strerror(0) doesn't return anything? on mine, it returns "Success".


A program that reports, "*** ERROR *** Cannot open whatever, Success"
would generally be considered a poor program.
Also, you're misreading it - "Unknown Error!" is set NOT on errno 0, but
on errno that's larger than the largest value for which an error message
is defined [on a typical modern system, strerror would return "Unknown \
Error 500" for that case]


strerror will return a message for any value of errno that the
implementation uses. My change is so that you get something vaguely
sensible if fopen does not set errno.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 22 '06 #7
On 2006-03-22, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Jordan Abel wrote:
On 2006-03-21, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Vladimir S. Oka wrote:
> /* // this chunk commented out by me
>
> if ( errno <= sys_nerr )
> errmess = sys_errlist[errno];
> else
> errmess = "Unknown error!";
>
> */
if (errno)
errmess = strerror(errno); // added by me

Is what you want here.
You also want:
else
errmess = "Unknown error!";

from the original code. Otherwise errmess is not set to anything if
errno==0.


strerror(0) doesn't return anything? on mine, it returns "Success".


A program that reports, "*** ERROR *** Cannot open whatever, Success"
would generally be considered a poor program.


Actually having errno set to 0 without knowing it might be 0, though, is
rare. I will agree, though, that "losing" the value of errno because
another intervening call sets it to something else, is poor coding
practice.
Also, you're misreading it - "Unknown Error!" is set NOT on errno 0, but
on errno that's larger than the largest value for which an error message
is defined [on a typical modern system, strerror would return "Unknown \
Error 500" for that case]


strerror will return a message for any value of errno that the
implementation uses. My change is so that you get something vaguely
sensible if fopen does not set errno.


Your change isn't anything near equivalent to the original code, though,
so I was thrown off. Also, errno will be whatever was there before, NOT
zero. No library function sets errno to 0, and it's often set to
something other than 0 even by a successful function [on many systems,
the first call to any stdio function will set it if either stdin or
stdout is not an interactive device]

My point was that handling errno==0 is not what the original code's
errmess="Unknown error!"; did, so just leaving it in wouldn't really
help. I just realized that he changed the semantics to if(errno), so it
might make sense to have the else clause regardless, but you'd then have
to initialize errno to 0 yourself. Whether fopen sets it and what it
sets it to is, of course, implementation-defined, but it will never
_clear_ errno.
Mar 22 '06 #8
Jordan Abel wrote:
On 2006-03-22, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Jordan Abel wrote:
On 2006-03-21, Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Vladimir S. Oka wrote:
>> /* // this chunk commented out by me
>>
>> if ( errno <= sys_nerr )
>> errmess = sys_errlist[errno];
>> else
>> errmess = "Unknown error!";
>>
>> */
> if (errno)
> errmess = strerror(errno); // added by me
>
> Is what you want here.
You also want:
else
errmess = "Unknown error!";

from the original code. Otherwise errmess is not set to anything if
errno==0.
strerror(0) doesn't return anything? on mine, it returns "Success". A program that reports, "*** ERROR *** Cannot open whatever, Success"
would generally be considered a poor program.


Actually having errno set to 0 without knowing it might be 0, though, is
rare. I will agree, though, that "losing" the value of errno because
another intervening call sets it to something else, is poor coding
practice.


fopen is not required to set errno, so the program has to allow for it.
Also, you're misreading it - "Unknown Error!" is set NOT on errno 0, but
on errno that's larger than the largest value for which an error message
is defined [on a typical modern system, strerror would return "Unknown \
Error 500" for that case]

strerror will return a message for any value of errno that the
implementation uses. My change is so that you get something vaguely
sensible if fopen does not set errno.


Your change isn't anything near equivalent to the original code, though,
so I was thrown off. Also, errno will be whatever was there before, NOT
zero. No library function sets errno to 0, and it's often set to
something other than 0 even by a successful function [on many systems,
the first call to any stdio function will set it if either stdin or
stdout is not an interactive device]


If I recall correctly the code Vladimir posted set errno to 0 before
calling fopen, and I believe he was correct to do this.
My point was that handling errno==0 is not what the original code's
errmess="Unknown error!"; did, so just leaving it in wouldn't really
help.
Agreed. I was improving Vladimir's version, not the original.
I just realized that he changed the semantics to if(errno), so it
might make sense to have the else clause regardless, but you'd then have
to initialize errno to 0 yourself. Whether fopen sets it and what it
sets it to is, of course, implementation-defined, but it will never
_clear_ errno.


OK, in that case I think we probably agree on the correct thing which is
to set errno to 0 before the call (which I believe was done) and trap it
being 0 so that you know if fopen has not set it.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 22 '06 #9
In article <46************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Welcome to the group Brennan. The question may be simple but it is what
we are here for.


Thanks! And thanks to all who responded, I now feel more confident about
my changes. I don't know if I can ever hope to have the kind of grasp of
C implementations as you guys (where do you learn all that?), but it's
nice to know where to come with such questions.

;)
Mar 23 '06 #10
Brennan Young wrote:
In article <46************@news.flash-gordon.me.uk>,
Flash Gordon <sp**@flash-gordon.me.uk> wrote:
Welcome to the group Brennan. The question may be simple but it is what
we are here for.


Thanks! And thanks to all who responded, I now feel more confident about
my changes. I don't know if I can ever hope to have the kind of grasp of
C implementations as you guys (where do you learn all that?), but it's
nice to know where to come with such questions.

;)


We learn by posting here and having our errors pointed out to us ;-)

Also reading good books, the comp.lang.c FAQ, and experience.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Mar 23 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: Jason | last post by:
Let's say I have an html form with 20 or 30 fields in it. The form submits the fields via POST to a php page which updates a table in a database with the $_POST vars. Which makes more sense? ...
6
by: Hennie de Nooijer | last post by:
Hi, Currently we're a building a metadatadriven datawarehouse in SQL Server 2000. We're investigating the possibility of the updating tables with enormeous number of updates and insert and the...
3
by: Robin Tucker | last post by:
Hi there, I have a database on my test machine that will need to be installed on users machines. I would like to create the database with the given schema on the users machine and also with...
26
by: puzzled | last post by:
Okay, so my subject sounds a bit crass. As much as I'd like to totally embrace css and avoid "deprecated" usage, sometimes the deprecated stuff is so much easier and more effective. Plus, it at...
4
by: Darrel | last post by:
I'm creating a table that contains multiple records pulled out of the database. I'm building the table myself and passing it to the page since the table needs to be fairly customized (ie, a...
14
by: el_sid | last post by:
Our developers have experienced a problem with updating Web References in Visual Studio.NET 2003. Normally, when a web service class (.asmx) is created, updating the Web Reference will...
34
by: Jeff | last post by:
For years I have been using VBA extensively for updating data to tables after processing. By this I mean if I had to do some intensive processing that resulted in data in temp tables, I would have...
5
by: Mark R. Dawson | last post by:
Hi all, I may be missing something with how databinding works but I have bound a datasource to a control and everything is great, the control updates to reflect the state of my datasource when I...
16
by: Stevo | last post by:
I'm guessing this is a laughably obvious answer to many here, but it's not to me (and I don't have a server or any knowledge of PHP to be able to try it). It's not strictly a PHP question, but...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.