Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


IRC in 2024!? - Page 8
New on LowEndTalk? Please Register and read our Community Rules.

All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.

IRC in 2024!?

1234568»

Comments

  • Not_OlesNot_Oles Moderator, Patron Provider

    Trying ii IRC client from suckless.org.

    Tutorial at https://www.reddit.com/r/vim/comments/48t7ws/vim_ii_irc_client_xpost_runixporn/

    Using the ii installed at ctrl-c.club, from which Libera.chat seems to disallow certain connections. So, instead of Libera, reverting to Freenode for this trial.

    About ii:

    ii creates in and out directories in ~/irc/$server_name. One uses command line tools like tail and echo to read and write messages. One reads from the out file and writes to the in file. What could be simpler . . . or perhaps more masochistic? :)

    A few snippets:

    tom@ctrl-c:~$ ii -s irc.freenode.net
    NICK tom
    USER tom localhost irc.freenode.net :tom
    
    1713657107 :*.freenode.net NOTICE * :*** Looking up your ident...
    1713657107 :*.freenode.net NOTICE * :*** Looking up your hostname...
    1713657107 PING :e\bardGUTZ
    1713657107 :*.freenode.net NOTICE tom :*** Found your hostname (ctrl-c.club)
    1713657108 :*.freenode.net NOTICE tom :*** Could not find your ident, using ~tom instead.
    1713657108 :*.freenode.net 001 tom :Welcome to the freenode IRC Network [email protected]
    1713657108 :*.freenode.net 002 tom :Your host is *.freenode.net, running version InspIRCd-3
    1713657108 :*.freenode.net 003 tom :This server was created 05:19:49 Jan 21 2024
      [ . . . ]
    1713657108 :*.freenode.net 251 tom :There are 19 users and 5644 invisible on 10 servers
    1713657108 :*.freenode.net 252 tom 9 :operator(s) online
    1713657108 :*.freenode.net 253 tom 11 :unknown connections
    1713657108 :*.freenode.net 254 tom 10458 :channels formed
    1713657108 :*.freenode.net 255 tom :I have 1734 clients and 1 servers
    1713657108 :*.freenode.net 265 tom :Current local users: 1734  Max: 1949
    1713657108 :*.freenode.net 266 tom :Current global users: 5663  Max: 7589
    1713657108 :*.freenode.net 375 tom :*.freenode.net message of the day
    1713657108 :*.freenode.net 372 tom :  Hello, World!
    1713657108 :*.freenode.net 372 tom : 
    1713657108 :*.freenode.net 372 tom :  Welcome to the
    1713657108 :*.freenode.net 372 tom :          __                               _
    1713657108 :*.freenode.net 372 tom :         / _|_ __ ___  ___ _ __   ___   __| | ___
    1713657108 :*.freenode.net 372 tom :        | |_| '__/ _ \/ _ \ '_ \ / _ \ / _` |/ _ \
    1713657108 :*.freenode.net 372 tom :        |  _| | |  __/  __/ | | | (_) | (_| |  __/
    1713657108 :*.freenode.net 372 tom :        |_| |_|  \___|\___|_| |_|\___/ \__,_|\___|
    1713657108 :*.freenode.net 372 tom :                                   AUTONOMOUS ZONE
    1713657108 :*.freenode.net 372 tom : 
    

    In a second terminal window:

    tom@ctrl-c:~/irc/irc.freenode.net$ ls
    global  harambe  in  out  tom
    tom@ctrl-c:~/irc/irc.freenode.net$ echo "/JOIN #freenode" > in
    tom@ctrl-c:~/irc/irc.freenode.net$ 
    

    Back to the first terminal window:

    1713657714 :[email protected] JOIN :#freenode
    1713657714 :*.freenode.net 332 tom #freenode :Welcome to #Freenode | www.freenode.net | For IRC or services help, please /join #help | Join #freenode-radio to listen to our very own radio | for trivia /join #trivia | For idle rpg /join #irpg | Channel Rules: https://wiki.freenode.net/view/Freenode | Winner for March is HurricaneTornado!
    1713657714 :*.freenode.net 333 tom #freenode [email protected] :1711975239
      [ . . . ]
    1713657714 :*.freenode.net 366 tom #freenode :End of /NAMES list.
    1713657715 :[email protected] NOTICE tom :[#freenode] Welcome to #freenode.
    1713657715 :[email protected] NOTICE tom :[#freenode] Please read #freenode channel rules: https://wiki.freenode.net/view/Freenode
    1713657715 :[email protected] NOTICE tom :[#freenode] For general chat please join #chat | If you joined #freenode from a web link make sure you are in the right channel
    1713657727 :[email protected] JOIN :#freenode
    1713657750 :[email protected] JOIN :#freenode
    1713657834 PING :*.freenode.net
    1713657954 PING :*.freenode.net
    1713658016 :hussam!~hussam@freenode/user/hussam QUIT :Ping timeout: 120 seconds
    1713658065 :[email protected] QUIT :Quit: Page closed
    1713658070 :[email protected] QUIT :Quit: Page closed
    1713658074 PING :*.freenode.net
    1713658079 :[email protected] JOIN :#freenode
    1713658097 :hussam!~hussam@freenode/user/hussam JOIN :#freenode
    1713658106 :[email protected] QUIT :Quit: Page closed
    1713658194 PING :*.freenode.net
    
  • Not_OlesNot_Oles Moderator, Patron Provider
  • Not_OlesNot_Oles Moderator, Patron Provider

    This is the main function from ii.c. Is anyone here good at C and interested in this ii code? :)

       795  int
       796  main(int argc, char *argv[])
       797  {
       798          struct passwd *spw;
       799          const char *key = NULL, *fullname = NULL, *host = "";
       800          const char *uds = NULL, *service = "6667";
       801          char prefix[PATH_MAX];
       802          int ircfd, r;
       803  
       804          /* use nickname and home dir of user by default */
       805          if (!(spw = getpwuid(getuid())))
       806                  die("%s: getpwuid: %s\n", argv0, strerror(errno));
       807  
       808          strlcpy(nick, spw->pw_name, sizeof(nick));
       809          snprintf(prefix, sizeof(prefix), "%s/irc", spw->pw_dir);
       810  
       811          ARGBEGIN {
       812          case 'f':
       813                  fullname = EARGF(usage());
       814                  break;
       815          case 'i':
       816                  strlcpy(prefix, EARGF(usage()), sizeof(prefix));
       817                  break;
       818          case 'k':
       819                  key = getenv(EARGF(usage()));
       820                  break;
       821          case 'n':
       822                  strlcpy(nick, EARGF(usage()), sizeof(nick));
       823                  break;
       824          case 'p':
       825                  service = EARGF(usage());
       826                  break;
       827          case 's':
       828                  host = EARGF(usage());
       829                  break;
       830          case 'u':
       831                  uds = EARGF(usage());
       832                  break;
       833          default:
       834                  usage();
       835                  break;
       836          } ARGEND
       837  
       838          if (!*host)
       839                  usage();
       840  
       841          if (uds)
       842                  ircfd = udsopen(uds);
       843          else
       844                  ircfd = tcpopen(host, service);
       845  
       846  #ifdef __OpenBSD__
       847          /* OpenBSD pledge(2) support */
       848          if (pledge("stdio rpath wpath cpath dpath", NULL) == -1)
       849                  die("%s: pledge: %s\n", argv0, strerror(errno));
       850  #endif
       851  
       852          r = snprintf(ircpath, sizeof(ircpath), "%s/%s", prefix, host);
       853          if (r < 0 || (size_t)r >= sizeof(ircpath))
       854                  die("%s: path to irc directory too long\n", argv0);
       855          create_dirtree(ircpath);
       856  
       857          channelmaster = channel_add(""); /* master channel */
       858          if (key)
       859                  loginkey(ircfd, key);
       860          loginuser(ircfd, host, fullname && *fullname ? fullname : nick);
       861          setup();
       862          run(ircfd, host);
       863          cleanup();
       864  
       865          return 0;
       866  }
    
  • It's pleasingly clean code. I like their macronized argument parsing. Getopt is annoyingly convoluted (and GPL'd if i remember correctly). I usually use argtable (who really enjoys writing argument parsing code after all? ...) but generalizing it down to some macros to be included in some kind of common header could probably work out quite nicely too.

    Thanked by 1Not_Oles
  • Not_OlesNot_Oles Moderator, Patron Provider

    @totally_not_banned

    Thanks for your comment!

    Looks like you are talking about three different ways of processing command line arguments: macro, getopt, and argtable?

    Maybe pointers and loops provide a fourth way of processing command line arguments? Here is discussion of a K&R code example using loops to parse arguments to the find utility. See also HN discussion.

    Briefly, the K&R find code uses pointers and loops. There is a while loop and a for loop. ". . . [T]he for loop traverses concatenated flags (i.e., it moves the pointer from the “x” to the “n” in “-xn”) and the while loop traverses separated flags (i.e., it moves the pointer from the “-x” to the “-n” in “-x -n”)." I think this K&R code is not what you meant by "macronized."

    @totally_not_banned said:

    1. "macronized"

    FreeBSD has an ARG(3) function. Plan 9 also had an ARG(2) function. These man pages talk about ARGBEGIN and ARGEND, so I guess they must be relevant to what you mean by "macronized?"

    1. getopt

    There is an example of getopt() in the GNU man 3 getopt page.

    1. argtable

    From https://www.argtable.org/ : (This page also has code examples.)

    "Argtable is an open source ANSI C library that parses GNU-style command-line options. It simplifies command-line parsing by defining a declarative-style API that you can use to specify what your command-line syntax looks like. Argtable will automatically generate consistent error handling logic and textual descriptions of the command line syntax, which are essential but tedious to implement for a robust CLI program."

    See also https://github.com/argtable/argtable3

    1. (macro, again?) generalizing it down to some macros to be included in some kind of common header

    K&R says:

    "4.11.2 Macro Substitution

    A definition has the form
    #define name replacement text

    It calls for a macro substitution of the simplest kind - subsequent occurrences of the
    token name will be replaced by the replacement text. "

    For ii ARGBEGIN and ARGEND are defined in the arg.h header which is part of the ii source code (git clone https://git.suckless.org/ii).

        12  #define ARGBEGIN        for (argv0 = *argv, argv++, argc--;\
        13                                          argv[0] && argv[0][0] == '-'\
        14                                          && argv[0][1];\
        15                                          argc--, argv++) {\
        16                                  char argc_;\
        17                                  char **argv_;\
        18                                  int brk_;\
        19                                  if (argv[0][1] == '-' && argv[0][2] == '\0') {\
        20                                          argv++;\
        21                                          argc--;\
        22                                          break;\
        23                                  }\
        24                                  int i_;\
        25                                  for (i_ = 1, brk_ = 0, argv_ = argv;\
        26                                                  argv[0][i_] && !brk_;\
        27                                                  i_++) {\
        28                                          if (argv_ != argv)\
        29                                                  break;\
        30                                          argc_ = argv[0][i_];\
        31                                          switch (argc_)
        32
        33  #define ARGEND                  }\
        34                          }
        35
    
  • edited April 22

    @Not_Oles said:
    Looks like you are talking about three different ways of processing command line arguments: macro, getopt, and argtable?

    Maybe pointers and loops provide a fourth way of processing command line arguments? Here is discussion of a K&R code example using loops to parse arguments to the find utility. See also HN discussion.

    Briefly, the K&R find code uses pointers and loops. There is a while loop and a for loop. ". . . [T]he for loop traverses concatenated flags (i.e., it moves the pointer from the “x” to the “n” in “-xn”) and the while loop traverses separated flags (i.e., it moves the pointer from the “-x” to the “-n” in “-x -n”)." I think this K&R code is not what you meant by "macronized."

    Well, there's a bunch of ways options can be parsed. I'd guess the most common ones are likely getopt and brewing something custom.

    @totally_not_banned said:

    1. "macronized"

    FreeBSD has an ARG(3) function. Plan 9 also had an ARG(2) function. These man pages talk about ARGBEGIN and ARGEND, so I guess they must be relevant to what you mean by "macronized?"

    Kind of, yes. I was not aware of FreeBSD formalizing any kind of argument parsing macros but if it does that obviously also fits the description. I was basically thinking of any kind of any kind of custom code approach boiled down to macros for simple reuse, even if in this case it's somewhat arguable how custom system supplied code actually is.

    1. (macro, again?) generalizing it down to some macros to be included in some kind of common header

    K&R says:

    "4.11.2 Macro Substitution

    A definition has the form
    #define name replacement text

    It calls for a macro substitution of the simplest kind - subsequent occurrences of the
    token name will be replaced by the replacement text. "

    Well, i'm really just still going on about the same thing :)

    For ii ARGBEGIN and ARGEND are defined in the arg.h header which is part of the ii source code (git clone https://git.suckless.org/ii).

        12  #define ARGBEGIN        for (argv0 = *argv, argv++, argc--;\
        13                                          argv[0] && argv[0][0] == '-'\
        14                                          && argv[0][1];\
        15                                          argc--, argv++) {\
        16                                  char argc_;\
        17                                  char **argv_;\
        18                                  int brk_;\
        19                                  if (argv[0][1] == '-' && argv[0][2] == '\0') {\
        20                                          argv++;\
        21                                          argc--;\
        22                                          break;\
        23                                  }\
        24                                  int i_;\
        25                                  for (i_ = 1, brk_ = 0, argv_ = argv;\
        26                                                  argv[0][i_] && !brk_;\
        27                                                  i_++) {\
        28                                          if (argv_ != argv)\
        29                                                  break;\
        30                                          argc_ = argv[0][i_];\
        31                                          switch (argc_)
        32
        33  #define ARGEND                  }\
        34                          }
        35
    

    That'll obviously do the job and it's a very suckless approach to it. The thing with argument parsing is that you don't really safe a whole lot by simplifying it. Sure going for something like argtable is a little decadent but you automatically get some nice usage description with very little actual code of your own and all that while not having much impact on the complexity of your code (you easily statically link against argtable so you don't incur a dependency or anything).

    If your goal is of the suckless kind as in achieving the absolute maximum of minimalism using anything more than a more or less simple loop is obviously prohibitive but in general i don't think any approach can be seen as objectively better than the other here. It's really mostly about style, personal preference and actual circumstances. Personally i'd still very much prefer suckless's idea over getopt most of the time though.

    Thanked by 1Not_Oles
  • Not_OlesNot_Oles Moderator, Patron Provider

    Hey! Hope you guys are doing great! I'm trying irssi. It seems to work. :) Libera requires SASL to connect from ctrl-c.club.

Sign In or Register to comment.