Fix memory leak issue - RQ161111-00886
[platform/upstream/edbus.git] / src / bin / notify-send.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <limits.h>
9 #include <errno.h>
10 #include <getopt.h>
11 #include <sysexits.h>
12
13 #include <Ecore.h>
14 #include <E_Notify.h>
15
16 #define S(X) #X
17
18 #define CHECK(X) do { \
19   if (!X) \
20     { \
21        fprintf(stderr, "%s:%i: Error calling %s!\n", __FILE__, __LINE__, S(X)); \
22        exit(1); \
23     } \
24 } while (0)
25
26 void
27 version(void)
28 {
29   printf("e-notify-send "VERSION"\n");
30 }
31
32 void
33 usage(void)
34 {
35   printf("Usage:\n"
36          "  e-notify-send [OPTION...] <SUMMARY> [BODY] - create a notification\n"
37          "\n"
38          "Help Options:\n"
39          "  -?, --help                        Show help options\n"
40          "\n"
41          "Application Options:\n"
42          "  -n, --name=NAME                   Specifies the application name to use (default is e-notify-send).\n"
43          "  -u, --urgency=LEVEL               Specifies the urgency level (low, normal, critical).\n"
44          "  -t, --expire-time=TIME            Specifies the timeout in milliseconds at which to expire the notification.\n"
45          "  -r, --replace=ID                  Specifies the ID of notification to replace.\n"
46          "  -p, --print-id                    Prints the ID of notification to STDOUT.\n"
47          "  -i, --icon=ICON                   Specifies an icon filename or stock icon to display.\n"
48          "  -c, --category=TYPE               Specifies the notification category.\n"
49          "  -v, --version                     Version of the package.\n"
50          "\n");
51 }
52
53 int
54 read_int_arg(long long *result, const char *name, intmax_t min, intmax_t max)
55 {
56   char *endptr;
57
58   errno = 0;  
59   *result = strtoll(optarg, &endptr, 10);
60   if ((errno != 0 && *result == 0) || endptr == optarg) 
61     {
62        fprintf(stderr, "Cannot parse integer value '%s' for %s\n", optarg, name);
63        return 0;
64     }
65   else if (*result > max || *result < min)
66     {
67        fprintf(stderr, "Integer value '%s' for %s out of range\n", optarg, name);
68        return 0;
69     }
70
71   return 1;
72 }
73
74 void 
75 send_cb(void *user_data __UNUSED__, void *method_return, DBusError *error __UNUSED__)
76 {
77    E_Notification_Return_Notify *r = method_return;
78
79    if(!r)
80      return;
81
82    printf("%u\n", r->notification_id );
83
84    ecore_main_loop_quit();
85 }
86
87 int
88 main(int argc, char **argv)
89 {
90   int ch;
91   long long value;
92   int print_id = 0;
93   E_Notification *n;
94
95   CHECK(eina_init());
96   CHECK(ecore_init());
97   CHECK(e_notification_init());
98   n = e_notification_new();
99   e_notification_app_name_set(n, "e-notify-send");
100   e_notification_timeout_set(n, -1);
101
102   /* options descriptor */
103   static struct option longopts[] = {
104       { "help",        no_argument,            NULL,           '?' },
105       { "name",        required_argument,      NULL,           'n' },
106       { "urgency",     required_argument,      NULL,           'u' },
107       { "expire-time", required_argument,      NULL,           't' },
108       { "replace",     required_argument,      NULL,           'r' },
109       { "print-id",    no_argument,            NULL,           'p' },
110       { "icon",        required_argument,      NULL,           'i' },
111       { "category",    required_argument,      NULL,           'c' },
112       { "version",     no_argument,            NULL,           'v' },
113       { NULL,          0,                      NULL,             0 }
114   };
115
116   while ((ch = getopt_long(argc, argv, "p?vn:u:t:r:i:c:", longopts, NULL)) != -1)
117     switch (ch) {
118     case '?':
119       usage();
120       goto exit_success;
121       break;
122     case 'v':
123       version();
124       goto exit_success;
125       break;
126     case 'n':
127       e_notification_app_name_set(n, optarg);
128       break;
129     case 'u':
130       if (!strcasecmp(optarg, "low"))
131         e_notification_hint_urgency_set(n, E_NOTIFICATION_URGENCY_LOW);
132       else if (!strcasecmp(optarg, "normal"))
133         e_notification_hint_urgency_set(n, E_NOTIFICATION_URGENCY_NORMAL);
134       else if (!strcasecmp(optarg, "critical"))
135         e_notification_hint_urgency_set(n, E_NOTIFICATION_URGENCY_CRITICAL);
136       else
137         printf("Urgency level must be: low, normal or critical\n");
138       break;
139     case 't':
140       if (!read_int_arg(&value, "-t", INT_MIN, INT_MAX))
141         goto exit_failure;
142       else 
143         e_notification_timeout_set(n, (int)value);
144       break;
145     case 'r':
146       if (!read_int_arg(&value, "-r", 0, UINT_MAX))
147         goto exit_failure;
148       else
149         e_notification_replaces_id_set(n, (unsigned int)value);
150       break;
151     case 'i':
152       e_notification_app_icon_set(n, optarg);
153       break;
154     case 'c':
155       e_notification_hint_category_set(n, optarg);
156       break;
157     case 'p':
158       print_id = 1;
159       break;
160     default:
161       usage();
162       goto exit_failure;
163     }
164   argc -= optind;
165   argv += optind;
166
167   if (argc < 1)
168     {
169       usage();
170       goto exit_failure;
171     }
172
173   e_notification_summary_set(n, argv[0]);
174   if (argc > 1) e_notification_body_set(n, argv[1]);
175
176
177   if (print_id)
178     {
179        e_notification_send(n, send_cb, NULL);
180        ecore_main_loop_begin();
181     }
182   else
183     e_notification_send(n, NULL, NULL);
184
185 exit_success:
186   e_notification_unref(n);
187   e_notification_shutdown();
188   ecore_shutdown();
189   eina_shutdown();
190
191   return EXIT_SUCCESS;
192
193 exit_failure:
194   e_notification_unref(n);
195   e_notification_shutdown();
196   ecore_shutdown();
197   eina_shutdown();
198
199   return EXIT_FAILURE;
200 }