C program to "monitor" NGINX status with AF_INET
Starting with main(): the signature implies that we accept command-line arguments, but we ignore argc and argv, using the hard-coded HOST_ADDR and HOST_PORT instead.  This makes the program less flexible.

An improvement would be to use those values as defaults, but allow command-line arguments to override them:

 const char *server = HOST_ADDR;
 if (argc &gt; 1)
     server = argc[1];
 uint16_t port = 0;
 if (argc &gt; 2)
     port = atoi(argc[2]);
 if (port == 0)
     port = HOST_PORT;


Argument processing can get much more sophisticated than this, but there's the bare minimum for the job.

Note in particular that atoi(HOST_ADDR), after expansion, is atoi("127.0.0.1") which always evaluates to 127.  What you really want is to change the signature of socket_get() to accept a string hostname:

int socket_get(const char *i_addr, uint16_t i_port)
{
    struct sockaddr_in server;
    server.sin_addr.s_addr = inet_addr(HOST_ADDR);
    if (server.sin_addr.s_addr == INADDR_NONE)
        return -1;


Notice that inet_addr may fail, so handle that gracefully.



There are severe problems in send_alarm(), apart from immediately failing if the compiled-in host names ever change.

Although we're using strncpy() to avoid overrunning from_host, that's slightly dangerous because it can leave an unterminated string in the output (and I'd change that hard-coded 24 to sizeof from_host, too).  That's minor, as the fixed strings we're using won't overflow the storage.

A more serious problem is that to is only 20 chars long, and we're initialising it with a 20-char string.  That means it won't have a null terminator, which will cause undefined behaviour when it's accessed by any string functions (such as the printf()).  A safer version is

    char to[] = "user@example.com";


Finally, the sprintf() is really dangerous.  For some reason, we haven't used snprintf() here, so it's possible to overrun the output cmd, and in fact, it's actually guaranteed to do so, given that cmd is only 100 chars in size, and just adding the lengths of the format string and to will exceed that.

Thankfully, all the issues in this function are easily fixed, because I'm going to recommend removing it completely.  Instead of invoking mailx directly from this program, it's more flexible to provide the necessary output and leave it to the caller to decide what to do with it (this is in keeping with the "Unix Philosophy" - do one thing well, and support composition of tools).

My recommendation is to delete send_alarm() and change the calling code to

    if (socket_get(server, port)) {
        fprintf(stderr, "Can't connect to NGINX service on %s:%u!\n", server, (unsigned int)port);
        return 1;
    }


By writing output and returning non-zero when (and only when) we fail, we make it easy to use in shell scripts or with cron (cron will send you email if the command produces output, and this is a perfect example of how to cooperate with that).