1717#define XHOST_FILE_PATH "/etc/hosts"
1818#define XHOST_VERSION_MAX 1
1919#define XHOST_VERSION_MIN 0
20- #define XHOST_BUILD_NUMBER 5
20+ #define XHOST_BUILD_NUMBER 6
2121
2222typedef struct {
2323 xbool_t bAdd ;
2424 xbool_t bAppend ;
2525 xbool_t bRemove ;
2626 xbool_t bVerbose ;
2727 xbool_t bLines ;
28+ xbool_t bSearch ;
2829 xbool_t bComment ;
2930 xbool_t bDisplay ;
3031 xbool_t bUncomment ;
@@ -39,6 +40,7 @@ typedef struct {
3940 char sHost [XLINE_MAX ];
4041 char sLine [XLINE_MAX ];
4142 xbool_t bWholeWords ;
43+ xbool_t bSearch ;
4244 size_t nLineNumber ;
4345 xstring_t hosts ;
4446 xfile_t file ;
@@ -54,10 +56,10 @@ extern char *optarg;
5456
5557static void XHost_Usage (const char * pName )
5658{
57- printf ("=========================================================== \n" );
59+ printf ("==========================================================\n" );
5860 printf (" XHost (Add or modify hosts) - v%d.%d build %d (%s)\n" ,
5961 XHOST_VERSION_MAX , XHOST_VERSION_MIN , XHOST_BUILD_NUMBER , __DATE__ );
60- printf ("=========================================================== \n" );
62+ printf ("==========================================================\n" );
6163
6264 int i , nLength = strlen (pName ) + 6 ;
6365 char sWhiteSpace [nLength + 1 ];
@@ -66,7 +68,7 @@ static void XHost_Usage(const char *pName)
6668 sWhiteSpace [nLength ] = 0 ;
6769
6870 printf ("Usage: %s [-a <address>] [-n <hostname>] [-x <number>]\n" , pName );
69- printf (" %s [-c] [-u] [-r] [-d] [-l] [-v] [-w] [-h]\n\n" , sWhiteSpace );
71+ printf (" %s [-c] [-u] [-r] [-d] [-l] [-s] [- v] [-w] [-h]\n\n" , sWhiteSpace );
7072
7173 printf ("Options are:\n" );
7274 printf (" -a <address> # IP address\n" );
@@ -75,6 +77,7 @@ static void XHost_Usage(const char *pName)
7577 printf (" -c # Comment entry\n" );
7678 printf (" -u # Uncomment entry\n" );
7779 printf (" -r # Remove entry\n" );
80+ printf (" -s # Search Entry\n" );
7881 printf (" -l # Insert new line before entry\n" );
7982 printf (" -d # Display /etc/hosts file\n" );
8083 printf (" -w # Match whole words in entry\n" );
@@ -83,16 +86,16 @@ static void XHost_Usage(const char *pName)
8386
8487 printf ("Examples:\n" );
8588 printf ("1) %s -a 10.10.17.1 -n example.com\n" , pName );
86- printf ("2) %s -a 10.12.19.1 -r \n" , pName );
87- printf ("2 ) %s -n test.com -rd \n" , pName );
89+ printf ("2) %s -a 192.168.0.17 -rw \n" , pName );
90+ printf ("3 ) %s -n test.com -rdl \n" , pName );
8891}
8992
9093static int XHost_ParseArgs (xhost_args_t * pArgs , int argc , char * argv [])
9194{
9295 memset (pArgs , 0 , sizeof (xhost_args_t ));
9396 int opt = 0 ;
9497
95- while ((opt = getopt (argc , argv , "a:n:x:c1:d1:u1:l1:r1:v1:w1:h1" )) != -1 )
98+ while ((opt = getopt (argc , argv , "a:n:x:c1:d1:u1:l1:r1:s1: v1:w1:h1" )) != -1 )
9699 {
97100 switch (opt )
98101 {
@@ -104,6 +107,7 @@ static int XHost_ParseArgs(xhost_args_t *pArgs, int argc, char *argv[])
104107 case 'u' : pArgs -> bUncomment = XTRUE ; break ;
105108 case 'l' : pArgs -> bLines = XTRUE ; break ;
106109 case 'r' : pArgs -> bRemove = XTRUE ; break ;
110+ case 's' : pArgs -> bSearch = XTRUE ; break ;
107111 case 'v' : pArgs -> bVerbose = XTRUE ; break ;
108112 case 'w' : pArgs -> bWholeWords = XTRUE ; break ;
109113 case 'h' : return XSTDERR ;
@@ -114,11 +118,12 @@ static int XHost_ParseArgs(xhost_args_t *pArgs, int argc, char *argv[])
114118 xbool_t bHaveAddress = xstrused (pArgs -> sAddress );
115119 xbool_t bHaveHost = xstrused (pArgs -> sHost );
116120 xbool_t bModify = pArgs -> bRemove || pArgs -> bComment || pArgs -> bUncomment ;
121+ pArgs -> bAppend = !bModify && !pArgs -> bSearch && ((bHaveAddress && bHaveHost ) || pArgs -> nLineNumber );
117122
118- pArgs -> bAppend = !bModify && ((bHaveAddress && bHaveHost ) || pArgs -> nLineNumber );
119- if (bModify && !bHaveAddress && !bHaveHost && !pArgs -> nLineNumber ) return XSTDERR ;
123+ if ((bModify || pArgs -> bSearch ) && !bHaveAddress && !bHaveHost && !pArgs -> nLineNumber ) return XSTDERR ;
120124 if (!pArgs -> bAppend && !bModify ) pArgs -> bDisplay = XTRUE ;
121125 if (pArgs -> bVerbose ) xlog_enable (XLOG_DEBUG );
126+ if (pArgs -> bSearch ) pArgs -> bDisplay = XTRUE ;
122127
123128 return XSTDOK ;
124129}
@@ -127,6 +132,7 @@ static int XHost_InitContext(xhost_ctx_t *pCtx, xbool_t bReset)
127132{
128133 if (bReset )
129134 {
135+ pCtx -> bSearch = XFALSE ;
130136 pCtx -> bWholeWords = XFALSE ;
131137 pCtx -> nLineNumber = 0 ;
132138
@@ -497,66 +503,66 @@ static void XHost_AddLineNumber(xstring_t *pString, int nLine)
497503 XString_Append (pString , "%s " , XSTR_FMT_RESET );
498504}
499505
500- static int XHost_DisplayHosts (xbool_t bLines )
506+ static int XHost_DisplayHosts (xhost_ctx_t * pCtx , xbool_t bLines )
501507{
502- xhost_ctx_t ctx ;
503- XASSERT ((XHost_InitContext (& ctx , XTRUE ) > 0 ), xthrowe ("Failed to init context" ));
508+ XHost_ClearContext ( pCtx ) ;
509+ XASSERT ((XHost_InitContext (pCtx , XFALSE ) > 0 ), xthrowe ("Failed to init context" ));
504510
511+ size_t nLineNumber = 0 ;
505512 int nPosit = 0 ;
506- int nLine = 0 ;
507513
508- while (XFile_GetLine (& ctx . file , ctx . sLine , sizeof (ctx . sLine )) > 0 )
514+ while (XFile_GetLine (& pCtx -> file , pCtx -> sLine , sizeof (pCtx -> sLine )) > 0 )
509515 {
510516 nPosit = 0 ;
511- nLine ++ ;
517+ nLineNumber ++ ;
512518
513- while (ctx .sLine [nPosit ] && isspace ((unsigned char )ctx .sLine [nPosit ])) nPosit ++ ;
514- if (bLines ) XHost_AddLineNumber (& ctx .hosts , nLine );
519+ if (pCtx -> bSearch && (pCtx -> nLineNumber != nLineNumber && !XHost_SearchEntry (pCtx ))) continue ;
520+ while (pCtx -> sLine [nPosit ] && isspace ((unsigned char )pCtx -> sLine [nPosit ])) nPosit ++ ;
521+ if (bLines ) XHost_AddLineNumber (& pCtx -> hosts , nLineNumber );
515522
516- if (!ctx . sLine [nPosit ] || ctx . sLine [nPosit ] == '\n' )
523+ if (!pCtx -> sLine [nPosit ] || pCtx -> sLine [nPosit ] == '\n' )
517524 {
518- XString_Append (& ctx . hosts , "\n" );
525+ XString_Append (& pCtx -> hosts , "\n" );
519526 continue ;
520527 }
521528
522- if (ctx . sLine [nPosit ] == '#' )
529+ if (pCtx -> sLine [nPosit ] == '#' )
523530 {
524- XString_Append (& ctx . hosts , "%s%s%s" , XSTR_FMT_DIM , ctx . sLine , XSTR_FMT_RESET );
531+ XString_Append (& pCtx -> hosts , "%s%s%s" , XSTR_FMT_DIM , pCtx -> sLine , XSTR_FMT_RESET );
525532 continue ;
526533 }
527534
528535 int nEnd = nPosit ;
529- XString_Add (& ctx . hosts , ctx . sLine , nPosit );
530- while (ctx . sLine [nEnd ] && !isspace ((unsigned char )ctx . sLine [nEnd ])) nEnd ++ ;
536+ XString_Add (& pCtx -> hosts , pCtx -> sLine , nPosit );
537+ while (pCtx -> sLine [nEnd ] && !isspace ((unsigned char )pCtx -> sLine [nEnd ])) nEnd ++ ;
531538
532- XString_Append (& ctx . hosts , "%s" , XSTR_CLR_CYAN );
533- XString_Add (& ctx . hosts , & ctx . sLine [nPosit ], nEnd - nPosit );
534- XString_Append (& ctx . hosts , "%s" , XSTR_FMT_RESET );
539+ XString_Append (& pCtx -> hosts , "%s" , XSTR_CLR_CYAN );
540+ XString_Add (& pCtx -> hosts , & pCtx -> sLine [nPosit ], nEnd - nPosit );
541+ XString_Append (& pCtx -> hosts , "%s" , XSTR_FMT_RESET );
535542
536543 int nCommentPosit = nEnd ;
537- while (ctx . sLine [nCommentPosit ] && ctx . sLine [nCommentPosit ] != '#' ) nCommentPosit ++ ;
544+ while (pCtx -> sLine [nCommentPosit ] && pCtx -> sLine [nCommentPosit ] != '#' ) nCommentPosit ++ ;
538545
539- if (ctx . sLine [nCommentPosit ] && ctx . sLine [nCommentPosit ] == '#' )
546+ if (pCtx -> sLine [nCommentPosit ] && pCtx -> sLine [nCommentPosit ] == '#' )
540547 {
541- XString_Add (& ctx . hosts , & ctx . sLine [nEnd ], nCommentPosit - nEnd );
542- XString_Append (& ctx . hosts , "%s" , XSTR_FMT_DIM );
543- XString_Append (& ctx . hosts , "%s" , & ctx . sLine [nCommentPosit ]);
544- XString_Append (& ctx . hosts , "%s" , XSTR_FMT_RESET );
548+ XString_Add (& pCtx -> hosts , & pCtx -> sLine [nEnd ], nCommentPosit - nEnd );
549+ XString_Append (& pCtx -> hosts , "%s" , XSTR_FMT_DIM );
550+ XString_Append (& pCtx -> hosts , "%s" , & pCtx -> sLine [nCommentPosit ]);
551+ XString_Append (& pCtx -> hosts , "%s" , XSTR_FMT_RESET );
545552 }
546553 else
547554 {
548- size_t nLength = strlen (& ctx . sLine [nEnd ]);
549- XString_Add (& ctx . hosts , & ctx . sLine [nEnd ], nLength );
555+ size_t nLength = strlen (& pCtx -> sLine [nEnd ]);
556+ XString_Add (& pCtx -> hosts , & pCtx -> sLine [nEnd ], nLength );
550557 }
551558 }
552559
553- if (ctx . hosts .nLength )
560+ if (pCtx -> hosts .nLength )
554561 {
555562 xlog_useheap (XTRUE );
556- xlog ("%s" , ctx . hosts .pData );
563+ xlog ("%s" , pCtx -> hosts .pData );
557564 }
558565
559- XHost_ClearContext (& ctx );
560566 return XSTDNON ;
561567}
562568
@@ -578,14 +584,15 @@ int main(int argc, char *argv[])
578584 XASSERT ((XHost_InitContext (& ctx , XTRUE ) > 0 ), xthrowe ("Failed to init context" ));
579585 xstrncpy (ctx .sAddr , sizeof (ctx .sAddr ), args .sAddress );
580586 xstrncpy (ctx .sHost , sizeof (ctx .sHost ), args .sHost );
581- ctx .bWholeWords = args .bWholeWords ;
582587 ctx .nLineNumber = args .nLineNumber ;
588+ ctx .bWholeWords = args .bWholeWords ;
589+ ctx .bSearch = args .bSearch ;
583590
584591 if (args .bAppend ) nStatus = XHost_AddEntry (& ctx , args .bLines );
585592 else if (args .bRemove ) nStatus = XHost_RemoveEntry (& ctx , XFALSE );
586593 else if (args .bComment ) nStatus = XHost_RemoveEntry (& ctx , XTRUE );
587594 else if (args .bUncomment ) nStatus = XHost_UncommentEntry (& ctx );
588- if (!nStatus && args .bDisplay ) XHost_DisplayHosts (args .bLines );
595+ if (!nStatus && args .bDisplay ) XHost_DisplayHosts (& ctx , args .bLines );
589596
590597 XHost_ClearContext (& ctx );
591598 return nStatus ;
0 commit comments