Snarl notification C "script"

Discussion of Transmission that doesn't fit in the other categories
Post Reply
pecet
Posts: 3
Joined: Fri Mar 26, 2010 9:52 am

Snarl notification C "script"

Post by pecet »

Snarl is unified notification tool for Windows. http://www.fullphat.net/index.php
I wrote small and simple C program which simply sends information about torrent completion to Snarl client (for usage with script-torrent-done-filename setting of Transmission). Please enable Network notifications in Snarl settings before using it. It does not register any App or notification class, and use "Anonymous Notification" feature, because of my laziness.

Tested with transmission 2.04 and Snarl R2.3.

Pardon my code comments (they are in polish), I was too lazy to remove them, because most parts are adapted from simple network client which I wrote for network programming at my University.
As you can see IP of client and port are hardcoded, so change them to whatever suits you before compiling (9887 is default port for snarl).
Process is forked into background because of hangup of transmission when using external completion script (especially when client isn't working on remote machine - before socket timeout).

Code: Select all

const char* host = "192.168.1.12"; // adres ip na ktorym jest uruchomiony serwer
const int port = 9887; // port na ktorym dziala serwer

#include <stdlib.h> /* definicje kodów błędów zwracanych przez funkcje main() EXIT_ itp. */
#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>
#include <netinet/ip.h>

#include <arpa/inet.h>

int main(void) {
if (fork() != 0) { exit(0); } else {
        close(0); close(1); close(2);
        setpgrp();
        const int sock = socket(AF_INET, SOCK_STREAM, 0); // tworzymy nowe gniazdo
        struct sockaddr_in addr; // adres gniazda
        char buf[512]; // bufor
        int len; // dlugosc bufora


        if (sock == -1) { // jesli nie udalo sie utworzyc gniazda
                //perror("blad w sock()");  // wypisujemy blad
                return EXIT_FAILURE; // zwracamy kod bledu i zakanczamy program
        }
//      printf("jest socket");

        addr.sin_family = AF_INET; // rodzina adresow - tutaj internetowe
        addr.sin_port = htons(port); // port na ktorym ma dzialac serwer
                                // uzywamy funkcji htons aby przeksztalcic liczbe
                                // w lokalnej kolejnosci bajtow na kolejnosc sieciowa
        addr.sin_addr.s_addr = inet_addr(host); // ustawiamy adres sieciowy naszej struktury
                                        // za pomoca funkcji inet_addr ktora konwertuje
                                        // stringa z adresem do odpowiedniej liczby

        // podlaczamy sie z pomoca socketa i od razu sprawdzamy czy nie wystapil blad (-1)
        if (connect(sock, (struct sockaddr*) &addr, sizeof(addr)) == -1) {
                //perror("blad w connect()"); // zwracamy blad
                return EXIT_FAILURE; // i kod bledu
        }

                sprintf(buf, "type=SNP#?version=1.0#?action=notification#?app=Transmission#?title=Transmission (Torrent Completed)#?text=%s at %s#?timeout=10\r\0", getenv("TR_TORRENT_NAME"), getenv("TR_TIME_LOCALTIME"));
                len = strlen(buf); // ustawiamy zmienna len na dlugosc bufor

                // zapisujemy dane do gniazda, jesli funkcja zwroci -1 to blad
                if (write(sock, buf, len) == -1) {
//                        perror("blad w write()"); // wypisujemy blad
                        return EXIT_FAILURE; // zwracamy kod bledu
                }
//              printf("jest wyslane");

}

}

I know this code sucks but I hope someone, who is more lazy than I, will find it useful.
Post Reply