try not thinning when loading old-school automation lists
[ardour.git] / libs / ardour / callback.cc
1 #include <iostream>
2 #include <string>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
8 #include <cstdlib>
9 #include <sys/utsname.h>
10 #include <curl/curl.h>
11
12 #include <glibmm/fileutils.h>
13 #include <glibmm/miscutils.h>
14
15 #include "pbd/compose.h"
16 #include "pbd/strsplit.h"
17 #include "pbd/convert.h"
18
19 #include "ardour/filesystem_paths.h"
20
21 using namespace std;
22
23 #define PING_URL "http://ardour.org/pingback/versioncheck"
24 #define OFF_THE_HOOK ".offthehook"
25
26 static size_t
27 curl_write_data (char *bufptr, size_t size, size_t nitems, void *ptr)
28 {
29         /* we know its a string */
30
31         string* sptr = (string*) ptr;
32
33         for (size_t i = 0; i < nitems; ++i) {
34                 for (size_t n = 0; n < size; ++n) {
35                         if (*bufptr == '\n') {
36                                 break;
37                         }
38
39                         (*sptr) += *bufptr++;
40                 }
41         }
42
43         return size * nitems;
44 }
45
46 static string
47 watermark ()
48 {
49         return string();
50 }
51
52 void
53 block_mothership ()
54 {
55         string hangup = Glib::build_filename (ARDOUR::user_config_directory().to_string(), OFF_THE_HOOK);
56         int fd;
57         if ((fd = ::open (hangup.c_str(), O_RDWR|O_CREAT, 0600)) >= 0) {
58                 close (fd);
59         }
60 }
61
62 void
63 unblock_mothership ()
64 {
65         string hangup = Glib::build_filename (ARDOUR::user_config_directory().to_string(), OFF_THE_HOOK);
66         ::unlink (hangup.c_str());
67 }
68
69 bool
70 mothership_blocked ()
71 {
72         string hangup = Glib::build_filename (ARDOUR::user_config_directory().to_string(), OFF_THE_HOOK);
73         return Glib::file_test (hangup, Glib::FILE_TEST_EXISTS);
74 }
75
76 void
77 call_the_mothership (const string& version)
78 {
79         /* check if the user says never to do this
80          */
81
82         if (mothership_blocked()) {
83                 return;
84         }
85
86         CURL* c;
87         struct utsname utb;
88         std::string versionstr;
89
90         if (uname (&utb)) {
91                 return;
92         }
93
94         curl_global_init (CURL_GLOBAL_NOTHING);
95
96         c = curl_easy_init ();
97
98         string data;
99         string wm;
100
101         data = string_compose ("version=%1&platform=%2 %3 %4", version, utb.sysname, utb.release, utb.machine);
102
103         wm = watermark();
104         if (!wm.empty()) {
105                 data += string_compose ("&watermark=%1", wm);
106         }
107
108         curl_easy_setopt(c, CURLOPT_POSTFIELDS, data.c_str());
109         curl_easy_setopt(c, CURLOPT_URL, PING_URL);
110         curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, curl_write_data);
111         curl_easy_setopt(c, CURLOPT_WRITEDATA, &versionstr);
112
113         std::cerr << "Callback to ardour.org ...\n";
114
115         char errbuf[CURL_ERROR_SIZE];
116         curl_easy_setopt(c, CURLOPT_ERRORBUFFER, errbuf);
117
118         if (curl_easy_perform (c) == 0) {
119                 cerr << "Current release is " << versionstr << endl;
120
121                 vector<string> ours;
122                 vector<string> current;
123
124                 split (version, ours, '.');
125                 split (versionstr, current, '.');
126
127                 if (ours.size() == 3 && current.size() == 3) {
128
129                         int ours_n[3];
130                         int current_n[3];
131
132                         using namespace PBD;
133
134                         ours_n[0] = atoi (ours[0]);
135                         ours_n[1] = atoi (ours[1]);
136                         ours_n[2] = atoi (ours[2]);
137
138                         current_n[0] = atoi (current[0]);
139                         current_n[1] = atoi (current[1]);
140                         current_n[2] = atoi (current[2]);
141
142                         if (ours_n[0] < current_n[0] ||
143                             ((ours_n[0] == current_n[0]) && (ours_n[1] < current_n[1])) ||
144                             ((ours_n[0] == current_n[0]) && (ours_n[1] == current_n[1]) && (ours_n[2] < current_n[2]))) {
145                                 cerr << "TOO OLD\n";
146                         } else {
147                                 cerr << "CURRENT\n";
148                         }
149                 } else {
150                         cerr << "Unusual local version: " << version << endl;
151                 }
152         }
153
154         curl_easy_cleanup (c);
155 }