LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-04-2017, 09:21 AM   #1
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,357

Rep: Reputation: 211Reputation: 211Reputation: 211
ls recursive in C language ?


Hello,

I would like to learn C and try a simple ls recursive.

My program is here and it does not work. If you may have time, would you know where is the mistake eventually?
Code:

int fexiststatic(char *a_option){
  // this work too on MS Windows!
  char dir1[PATH_MAX]; 
  char *dir2;
  DIR *dip;
  strncpy( dir1 , "",  PATH_MAX  );
  strncpy( dir1 , a_option,  PATH_MAX  );

  struct stat st_buf; 
  int status; 
  int fileordir = 0 ; 

  status = stat ( dir1 , &st_buf);
  if (status != 0) {
    fileordir = 0;
  }

  // this is compatible to check if a file exists
  FILE *fp2check = fopen( dir1  ,"r");
  if( fp2check ) {
  // exists
  fileordir = 1; 
  fclose(fp2check);
  } 

  if (S_ISDIR (st_buf.st_mode)) {
    fileordir = 2; 
  }
return fileordir;
/////////////////////////////
}


  static void loaddir( char *mysearchdir )
  {
    printf( "Enter: %s \n" , mysearchdir );
    chdir( mysearchdir );

    unsigned filemax = 0;
    unsigned n=0;
    DIR *dirp;
    struct dirent *dp;
    char idata[2240][250];
    n = 0 ; 
    filemax = 0; 
    dirp = opendir( "." );
    while  ((dp = readdir( dirp )) != NULL  &&  
            n < sizeof idata / sizeof idata[ 0 ]) {
            if ( strcmp( dp->d_name , "." ) != 0 )
            if ( strcmp( dp->d_name , ".." ) != 0 )
            if ( dp->d_name[0] !=  '.' )
            {
	      if ( fexiststatic( dp->d_name ) == 2 )
	      {
	         loaddir( dp->d_name );
	      }
	      else
                 printf( "%s (%d)\n", dp->d_name , fexiststatic( dp->d_name ) );
            }
    }
    filemax = n-1 ; 
    closedir( dirp );
    //for( n = 0 ; n <= filemax ; n++)
    //    printf( "%s %d\n", idata[ n ] , fexiststatic( idata[ n ] )  );
    // if ( n > 1 )
    // qsort( idata, n , sizeof idata[0], compare_fun );
   }





int main(){
   char toxi[PATH_MAX];
   loaddir( getcwd( toxi, PATH_MAX ) );

   return 0;
}

A working solution is here:
Code:
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
// https://stackoverflow.com/questions/8436841/how-to-recursively-list-directories-in-c-on-linux

void listdir(const char *name, int indent)
{
    DIR *dir;
    struct dirent *entry;

    if (!(dir = opendir(name)))
        return;

    while ((entry = readdir(dir)) != NULL) 
    {
        if (entry->d_type == DT_DIR) 
	{
            char path[1024];

            if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
                continue;

            snprintf( path, sizeof(path), "%s/%s", name, entry->d_name);

            printf("%*s[%s]\n", indent, "", entry->d_name);
            listdir(path, indent + 2);
        } 
	else 
	{
            printf("%*s- %s\n", indent, "", entry->d_name);
        }
    }
    closedir(dir);
}



int main(void) 
{
    listdir( ".", 0);
    return 0;
}
 
Old 08-04-2017, 09:26 AM   #2
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 8,444
Blog Entries: 4

Rep: Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896
A very pragmatic way to help debug an errant recursive solution is to print log-messages to STDERR. Also, let one parameter to the function be an integer which is initially given the value zero, and which each recursive call increments by one ... thus, the variable becomes a "recursion-depth indicator" which you can use in your messages.

Usually, it becomes very evident, very quickly, where the problem is.

I have found these strategies to be much easier than fiddling around with "debuggers," which I almost never actually do.
 
2 members found this post helpful.
Old 08-04-2017, 09:34 AM   #3
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,235

Rep: Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979
> where is the mistake eventually?

You forgot to include any headers, like stdio.h, dirent.h, unistd.h
 
1 members found this post helpful.
Old 08-04-2017, 02:44 PM   #4
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_10{.0|.1|.2}
Posts: 4,454
Blog Entries: 6

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Xeratul, you have been participating here long enough to know that "does not work" is not a good problem description.

Please see the Site FAQ and links from that page with which you are by now familiar for guidance in forming your questions in future.

Posting large code segments without a useful description of your problem or how it is failing is not acceptable.

Please help others help you, and please help us keep the information in this forum useful and accessible for future visitors.
 
Old 08-04-2017, 03:33 PM   #5
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,357

Original Poster
Rep: Reputation: 211Reputation: 211Reputation: 211
Quote:
Originally Posted by astrogeek View Post
Xeratul, you have been participating here long enough to know that "does not work" is not a good problem description.

Please see the Site FAQ and links from that page with which you are by now familiar for guidance in forming your questions in future.

Posting large code segments without a useful description of your problem or how it is failing is not acceptable.

Please help others help you, and please help us keep the information in this forum useful and accessible for future visitors.
I will extend with more asked infos asap. No worries.

Please give me time!!
I am very sorry but I am currently very busy. (I do a backup of my data)
 
Old 08-04-2017, 04:10 PM   #6
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_10{.0|.1|.2}
Posts: 4,454
Blog Entries: 6

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by Xeratul View Post
I will extend with more asked infos asap. No worries.

Please give me time!!
I am very sorry but I am currently very busy. (I do a backup of my data)
Then I would ask that you refrain from posting until you have time to post a complete and properly asked question.

Others here, including myself also have our own schedules in addition to volunteering our time here. Please respect the time constraints of those offering help.

You have also formed a pattern of posting complete code examples with no actual question and little point other than sharing your code interest of the day. I ask that you refrain from doing that in the programming forum. If you wish to share your code then your blog space would be a more appropriate place to do that, and I encourage you to make use of it.

You often emphasize the importance of things that are minimal. Please make effort to minimize your own code examples to only that necessary to demonstrate the point of your own questions, accompanied by a well considered description of the specific problem. That too, will help others use their own limited time to help yourself and others.

Thank you for you help with this.
 
1 members found this post helpful.
Old 08-04-2017, 05:05 PM   #7
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,357

Original Poster
Rep: Reputation: 211Reputation: 211Reputation: 211
Quote:
Originally Posted by astrogeek View Post
Then I would ask that you refrain from posting until you have time to post a complete and properly asked question.

Others here, including myself also have our own schedules in addition to volunteering our time here. Please respect the time constraints of those offering help.

You have also formed a pattern of posting complete code examples with no actual question and little point other than sharing your code interest of the day. I ask that you refrain from doing that in the programming forum. If you wish to share your code then your blog space would be a more appropriate place to do that, and I encourage you to make use of it.

You often emphasize the importance of things that are minimal. Please make effort to minimize your own code examples to only that necessary to demonstrate the point of your own questions, accompanied by a well considered description of the specific problem. That too, will help others use their own limited time to help yourself and others.

Thank you for you help with this.

OK, I give you tomorrow more information. Good night.
 
Old 08-04-2017, 05:35 PM   #8
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_10{.0|.1|.2}
Posts: 4,454
Blog Entries: 6

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Quote:
Originally Posted by Xeratul View Post
OK, I give you tomorrow more information. Good night.
Please note that "more" information is not necessarily what is needed.

The point is to try to post "better" questions with well considered, minimal code examples specific to the questions being asked. All of which raises the quality and accessibility of the information posted here, and respects the time and knowledge contributions of others.

Thank you for considering these points.
 
Old 08-05-2017, 03:21 AM   #9
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,357

Original Poster
Rep: Reputation: 211Reputation: 211Reputation: 211
Quote:
Originally Posted by astrogeek View Post
Please note that "more" information is not necessarily what is needed.

The point is to try to post "better" questions with well considered, minimal code examples specific to the questions being asked. All of which raises the quality and accessibility of the information posted here, and respects the time and knowledge contributions of others.

Thank you for considering these points.
I tried with my all wishes and good intentions to make a good post. I added my complete code + looked for possible solutions and worked on the code.

I missed few lines of code and I did not add the debugging at that time because I thought that it was not necessary because of self explaining code.

I would be please not to made a tragedy because of my good intentions and motivation.

Could you stop me please!!!! thank you in advance
 
Old 08-05-2017, 03:30 AM   #10
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,357

Original Poster
Rep: Reputation: 211Reputation: 211Reputation: 211
Hello Guys,

Herewith the code which has been slightly improved and also a debugging code.

I hope that it may eventually help.

I am pleased to share with you this code and complete informations. This is not good, of course. I hope that fervent experienced programmers will not bash me again and again because of my beginner experience in programming.

C Language: I did not studied Informatics at school and I am learning at a slow motion. This explains why the code looks like beginner. Because I am.

LQ should moderate a bit for helping beginners to progress in informatics.

Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <dirent.h>
#include <ctype.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>

///////////////////////////////////
#include <ctype.h>  // fexist
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>
///////////////////////////////////
#include <unistd.h>  //define getcwd




#include <stdlib.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>


static int compare_fun( const void *p, const void *q)
{
  const char *l = p ; 
  const char *r = q ; 
  int cmp; 
  cmp = strcmp( l, r );
  return cmp; 
}




int fexiststatic(char *a_option){
  // this work too on MS Windows!
  char dir1[PATH_MAX]; 
  char *dir2;
  DIR *dip;
  strncpy( dir1 , "",  PATH_MAX  );
  strncpy( dir1 , a_option,  PATH_MAX  );

  struct stat st_buf; 
  int status; 
  int fileordir = 0 ; 

  status = stat ( dir1 , &st_buf);
  if (status != 0) {
    fileordir = 0;
  }

  // this is compatible to check if a file exists
  FILE *fp2check = fopen( dir1  ,"r");
  if( fp2check ) {
  // exists
  fileordir = 1; 
  fclose(fp2check);
  } 

  if (S_ISDIR (st_buf.st_mode)) {
    fileordir = 2; 
  }
return fileordir;
/////////////////////////////
}


  static void loaddir( char *mysearchdir )
  {
    printf( "Enter: %s \n" , mysearchdir );
    char newdir[PATH_MAX];
    //chdir( mysearchdir );

    unsigned filemax = 0;
    unsigned n=0;
    DIR *dirp;
    struct dirent *dp;
    char idata[2240][250];
    n = 0 ; 
    filemax = 0; 
    dirp = opendir( mysearchdir );
    while  ((dp = readdir( dirp )) != NULL  &&  
            n < sizeof idata / sizeof idata[ 0 ]) {
            if ( strcmp( dp->d_name , "." ) != 0 )
            if ( strcmp( dp->d_name , ".." ) != 0 )
            if ( dp->d_name[0] !=  '.' )
            {
             // strncpy( idata[ n++ ] , dp->d_name , 250 );
	      if ( fexiststatic( dp->d_name ) == 2 )
	      {
                 strncpy( newdir, mysearchdir , PATH_MAX );
                 strncat( newdir ,  "/"  , PATH_MAX - strlen( newdir ) -1 );
                 strncat( newdir ,  dp->d_name , PATH_MAX - strlen( newdir ) -1 );
	         //loaddir( dp->d_name );
	         loaddir( newdir );
	      }
	      else
	      {
                printf( "%s/%s (%d)\n", mysearchdir,  dp->d_name , fexiststatic( dp->d_name ) );
              }
            }
    }
    filemax = n-1 ; 
    closedir( dirp );

    //    printf( "%s %d\n", idata[ n ] , fexiststatic( idata[ n ] )  );
    // if ( n > 1 )
    //  qsort( idata, n , sizeof idata[0], compare_fun );
    //for( n = 0 ; n <= filemax ; n++)

 }




int main()
{
   char toxi[PATH_MAX];
   loaddir( getcwd( toxi, PATH_MAX ) );

   return 0;
}


Debugging output
Code:
~/source/sys/makelist.c (1)
~/source/sys/ncp.c (1)
~/source/sys/nwatch.c (1)
~/source/sys/ngetpass.c (1)
~/source/sys/nxdisplay.c (1)
~/source/sys/nbasename.c (1)
~/source/sys/nfexist.c (1)
~/source/sys/nfindtask.c (1)
~/source/sys/nlsrecursive.c (1)
Enter: ~/source/sys/tree 
~/source/sys/tree/testit.c (0)
~/source/sys/tree/hello.c (1)
~/source/sys/ndisplay.c (1)
~/source/sys/nln.c (1)
~/source/sys/nsplit.c (1)
~/source/sys/ncat.c (1)
~/source/sys/hello.c (1)
~/source/sys/Makefile (1)
~/source/sys/makelist (1)
~/source/sys/ncatmin.c (1)
~/source/sys/npresskey.c (1)
~/source/sys/nprintpid.c (1)
~/source/sys/ndd.c (1)
~/source/sys/nfilterhead.c (1)
~/source/sys/nfilterbasename.c (1)
~/source/sys/nlsdepth.c (1)
Enter: ~/source/sys/tree2 
~/source/sys/tree2/testfile.txt (0)
~/source/sys/nfilterprint.c (1)
~/source/sys/nlsfind.c (1)
It looks better now!! It is kinda working. The "(" ")" do show what the programme sees about the given file, i.e. if it is a DIRECTORY or a FILE. DIR = 2, and FILE = 1, 0 would means that there is nothing.

1) The programme looks terrific. 2) 0,1,2 arent working. 3) maybe a rewrite would be better or anything else. 4) for big directory, e.g. $HOME/, it gives Segmentation fault.

I can fairly say my opinion about the code.
Anything, looking at all this code, I believe that it is ugly. It is completely crap crap, mega crap.
Like in Spiderman: https://www.youtube.com/watch?v=Zs7PmoHpNhA

The problem is likely fexiststatic, I believe. Taking next step with file types, I could maybe give here an probably working programme, but I guarantee a segmentation fault since it looks to me that opendir opens too much dirs and does not close them on time.
The most recent version of the code is indicated herewith:
https://pastebin.com/raw/SjqxcLJC
This newer version works for /tmp or not that much files. However try to run it on /home and you'll get Segmentation Fault.

What do you think about code? Which possible potential of improvement would you advice? Maybe just a delete and rewrite? Or Xeratul should start enrolling in an informatics school ?

Last edited by Xeratul; 08-05-2017 at 04:32 AM.
 
Old 08-05-2017, 09:14 PM   #11
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_10{.0|.1|.2}
Posts: 4,454
Blog Entries: 6

Rep: Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394Reputation: 2394
Xeratul, no one is bashing you or your code. Please reconsider why you may feel that way.

I know there is a language barrier, but I must insist that you read my posts above once more and try to understand what I am telling you as your response indicates that you have not done so. I am only asking you to follow the LQ posting guidelines when posting to the Programming forum.

Please read and understand the posting guidelines in the Site FAQ and the links at bottom of that page. That is the standard by which posts in this forum are measured, for the benefit of all members.

Note also the heading at the top of each page in the forum:

Quote:
Programming This forum is for all programming questions.
If your object is mainly to share your code, or to engage in social interaction, we encourage you to do that, but please use your LQ blog space, or the General forum when you are not seeking help with a specific question.

When you do post to the programming forum, always try to begin your post with a clear description of the specific issue that you need help with, a clearly stated question, and post only a minimal code example which illustrates the specific issue you are having. The posts should be all about the clarity of the problem description and your question, not the posted code!

I wish to repeat this point, because it has been a recurring theme that you need to understand:

Quote:
Originally Posted by astrogeek View Post
You have also formed a pattern of posting complete code examples with no actual question and little point other than sharing your code interest of the day. I ask that you refrain from doing that in the programming forum. If you wish to share your code then your blog space would be a more appropriate place to do that, and I encourage you to make use of it.

You often emphasize the importance of things that are minimal. Please make effort to minimize your own code examples to only that necessary to demonstrate the point of your own questions, accompanied by a well considered description of the specific problem. That too, will help others use their own limited time to help yourself and others.
This is not about bashing you or your code in any way. It is not about enforcing rules. It is all about helping you to understand the importance of using the forums properly, showing respect for other members, and making the best use of your participation here at LQ.

Your help with this would be appreciated!
 
Old 08-05-2017, 11:49 PM   #12
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 3,235

Rep: Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979Reputation: 979
Please fix these warnings:
Code:
xeratul.c: In function 'fexiststatic':
xeratul.c:52:8: warning: unused variable 'dip' [-Wunused-variable]
   DIR *dip;
        ^
xeratul.c:51:9: warning: unused variable 'dir2' [-Wunused-variable]
   char *dir2;
         ^
xeratul.c: In function 'loaddir':
xeratul.c:92:9: warning: unused variable 'myfiletype' [-Wunused-variable]
     int myfiletype;
         ^
xeratul.c:87:14: warning: variable 'filemax' set but not used [-Wunused-but-set-variable]
     unsigned filemax = 0;
              ^
xeratul.c: At top level:
xeratul.c:36:12: warning: 'compare_fun' defined but not used [-Wunused-function]
 static int compare_fun( const void *p, const void *q)
 
Old 08-07-2017, 09:03 PM   #13
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 8,444
Blog Entries: 4

Rep: Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896Reputation: 2896
Quote:
Originally Posted by astrogeek View Post
Please note that "more" information is not necessarily what is needed.

The point is to try to post "better" questions with well considered, minimal code examples specific to the questions being asked. All of which raises the quality and accessibility of the information posted here, and respects the time and knowledge contributions of others.

Thank you for considering these points.
If I may add one other thought to this:

"When you post a new question to any forum, please bear in mind that your post will more-than-likely become eternal. People will continue to find it, for many years to come, as they "search" for this thing or that. Therefore, try to create the forum post ... the first time ... that they will be so-anxiously searching for! Let it be the forum thread which begins with a thoroughly spelled-out description of a problem situation – "Yes! Yes! That's me! Hallelujah! This, finally, is the thread I've been looking for!" – and a specific question, which directly facilitates(!) someone else providing a great answer that will also "live forever."

"Details, Details" will become extremely important in the future, when your thread will once again be read and the searcher first-and-foremost needs to know whether the thread is (still) relevant to them. (They are equally important in answering your question effectively, right now!) Think of it this way: you are not only seeking your answer now, but also creating a thing that may help a great many other people in the ... near and/or distant ... future.

"Post accordingly. Pretty please." It does make a difference.
 
2 members found this post helpful.
Old 08-08-2017, 11:34 AM   #14
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 9,557

Rep: Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810Reputation: 2810
Quote:
Originally Posted by Xeratul View Post
This newer version works for /tmp or not that much files. However try to run it on /home and you'll get Segmentation Fault.
if it segfaults it is not ok. You need to fix it.
Quote:
Originally Posted by Xeratul View Post
Which possible potential of improvement would you advice?
First of all you need to learn compiling. That means you need to be sure the compilation itself is ok. For this you need to use gcc -Wall and you need to fix all the warnings/errors reported by gcc. That will give you a lot of help to make better code.
You must not delete/rewrite, but understand your mistakes and improve your code.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Installed a new Thunderbird along with language pack, but new language ain't there. mark_alfred Linux - Software 17 07-23-2017 12:46 PM
[SOLVED] A problem. When using assembly language to call the C language function mirage1993 Programming 3 10-03-2014 08:15 AM
[SOLVED] How to change gtkspell language without changing Slackware language? André0991 Slackware 4 03-05-2014 03:09 PM
[SOLVED] Can the language of fedora boot message change to other language, zh_CN,e.g.? jimtony Fedora 2 01-11-2011 03:03 AM
Good linux chinese language language program? darsunt Linux - Software 1 04-10-2009 12:06 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 09:59 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration