1#!/bin/sh
2#---------------------------------------------
3#   xdg-icon-resource
4#
5#   Utility script to install icons on a Linux desktop.
6#
7#   Refer to the usage() function below for usage.
8#
9#   Copyright 2009-2010, Fathi Boudra <fabo@freedesktop.org>
10#   Copyright 2009-2010, Rex Dieter <rdieter@fedoraproject.org>
11#   Copyright 2006, Kevin Krammer <kevin.krammer@gmx.at>
12#   Copyright 2006, Jeremy White <jwhite@codeweavers.com>
13#
14#   LICENSE:
15#
16#---------------------------------------------
17
18manualpage()
19{
20cat << _MANUALPAGE
21_MANUALPAGE
22}
23
24usage()
25{
26cat << _USAGE
27_USAGE
28}
29
30#@xdg-utils-common@
31
32# Set GTK_UPDATE_ICON_CACHE to gtk-update-icon-cache executable path or
33# to "-" if not found.
34GTK_UPDATE_ICON_CACHE=
35find_gtk_update_icon_cache()
36{
37    [ -n "$GTK_UPDATE_ICON_CACHE" ] && return;
38
39    GTK_UPDATE_ICON_CACHE="-"
40    for x in `echo "$PATH:/opt/gnome/bin" | sed 's/:/ /g'`; do
41        DEBUG 3 "Checking $x for gtk-update-icon-cache"
42        if [ -x "$x/gtk-update-icon-cache" ] ; then
43            DEBUG 1 "Found $x/gtk-update-icon-cache"
44            GTK_UPDATE_ICON_CACHE="$x/gtk-update-icon-cache"
45            return
46        fi
47    done
48}
49
50# Start GNOME legacy workaround section
51need_dot_icon_path()
52{
53  # GTK < 2.6 uses ~/.icons but not XDG_DATA_HOME/icons
54  # The availability of gtk-update-icon-cache is used as indication
55  # of whether the system is using GTK 2.6 or later
56  find_gtk_update_icon_cache
57  [ "$GTK_UPDATE_ICON_CACHE" != "-" ] && return 1;
58  return 0;
59}
60
61update_icon_database()
62{
63   # Touch me, I'm dirty
64   touch "$1/.@NAME@-dummy"
65   rm -f "$1/.@NAME@-dummy"
66
67   # Don't create a cache if there wan't one already
68   if [ -f "$1/icon-theme.cache" ] ; then
69      find_gtk_update_icon_cache
70      if [ "$GTK_UPDATE_ICON_CACHE" != "-" ] ; then
71         DEBUG 1 "Running $GTK_UPDATE_ICON_CACHE -f -t \"$1\""
72         eval '$GTK_UPDATE_ICON_CACHE -f -t "$1"'$xdg_redirect_output
73         return
74      fi
75   fi
76}
77
78[ x"$1" != x"" ] || exit_failure_syntax
79
80mode=
81action=
82update=yes
83size=
84theme=hicolor
85context=apps
86icon_file=
87icon_name=
88
89case $1 in
90  install)
91    action=install
92    ;;
93
94  uninstall)
95    action=uninstall
96    ;;
97
98  forceupdate)
99    action=forceupdate
100    ;;
101
102  *)
103    exit_failure_syntax "unknown command '$1'"
104    ;;
105esac
106
107shift
108
109vendor=true
110while [ $# -gt 0 ] ; do
111    parm="$1"
112    shift
113
114    case $parm in
115      --noupdate)
116        update=no
117        ;;
118
119      --mode)
120        if [ -z "$1" ] ; then
121            exit_failure_syntax "mode argument missing for --mode"
122        fi
123        case "$1" in
124          user)
125            mode="user"
126            ;;
127
128          system)
129            mode="system"
130            ;;
131
132          *)
133            exit_failure_syntax "unknown mode '$1'"
134            ;;
135        esac
136        shift
137        ;;
138
139      --theme)
140        if [ -z "$1" ] ; then
141            exit_failure_syntax "theme argument missing for --theme"
142        fi
143        theme="$1"
144        shift
145        ;;
146
147      --size)
148        if [ -z "$1" ] ; then
149            exit_failure_syntax "size argument missing for --size"
150        fi
151        if echo "$1" | grep '[^0-9]' > /dev/null 2> /dev/null; then
152            exit_failure_syntax "size argument must be numeric"
153        fi
154        size="$1"
155        shift
156        ;;
157
158      --context)
159        if [ -z "$1" ] ; then
160            exit_failure_syntax "context argument missing for --context"
161        fi
162        context="$1"
163        shift
164        ;;
165
166      --novendor)
167        vendor=false
168        ;;
169
170      -*)
171        exit_failure_syntax "unexpected option '$parm'"
172        ;;
173
174      *)
175        if [ -n "$icon_name" ] ; then
176            exit_failure_syntax "unexpected argument '$parm'"
177        elif [ -n "$icon_file" ] ; then
178            icon_name="$parm"
179        else
180            if [ "$action" = "install" ] ; then
181                check_input_file "$parm"
182            fi
183            icon_file="$parm"
184        fi
185        ;;
186    esac
187done
188
189# Shouldn't happen
190if [ -z "$action" ] ; then
191    exit_failure_syntax "command argument missing"
192fi
193
194# Shouldn't happen
195if [ -z "$context" ] ; then
196    exit_failure_syntax "context argument missing"
197fi
198
199if [ -n "$XDG_UTILS_INSTALL_MODE" ] ; then
200    if [ "$XDG_UTILS_INSTALL_MODE" = "system" ] ; then
201        mode="system"
202    elif [ "$XDG_UTILS_INSTALL_MODE" = "user" ] ; then
203        mode="user"
204    fi
205fi
206
207if [ -z "$mode" ] ; then
208    if [ `whoami` = "root" ] ; then
209       mode="system"
210    else
211       mode="user"
212    fi
213fi
214
215xdg_dir_name="icons/$theme"
216
217xdg_user_dir="$XDG_DATA_HOME"
218[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share"
219xdg_user_prefix="$xdg_user_dir/icons"
220xdg_user_dir="$xdg_user_dir/$xdg_dir_name"
221
222xdg_global_dir=
223xdg_global_prefix=
224xdg_system_dirs="$XDG_DATA_DIRS"
225[ -n "$xdg_system_dirs" ] || xdg_system_dirs="/usr/local/share/:/usr/share/"
226for x in `echo "$xdg_system_dirs" | sed 's/:/ /g'`; do
227   if [ -w $x/$xdg_dir_name ] ; then
228      xdg_global_prefix="$x/icons"
229      xdg_global_dir="$x/$xdg_dir_name"
230      break
231   fi
232done
233[ -w $xdg_global_dir ] || xdg_global_dir=
234
235dot_icon_dir=
236dot_base_dir=
237if [ x"$mode" = x"user" ] ; then
238    xdg_base_dir="$xdg_user_dir"
239    #Gnome 2.8 supports ~/.icons but not XDG_DATA_HOME
240    if need_dot_icon_path ; then
241        dot_icon_dir="$HOME/.icons"
242        dot_base_dir="$dot_icon_dir/$theme"
243    fi
244else
245    xdg_base_dir="$xdg_global_dir"
246    if [ -z "$xdg_base_dir" ] ; then
247        exit_failure_operation_impossible "No writable system icon directory found."
248    fi
249fi
250
251if [ x"$action" = x"forceupdate" ] ; then
252    if [ -n "$icon_file" ] ; then
253      exit_failure_syntax "unexpected argument '$icon_file'"
254    fi
255    update_icon_database $xdg_base_dir
256    if [ -n "$dot_icon_dir" ] ; then
257        if [ -d "$dot_icon_dir/" -a ! -L "$dot_icon_dir" ] ; then
258            update_icon_database $dot_base_dir
259        fi
260    fi
261    exit_success
262fi
263
264if [ -z "$icon_file" ] ; then
265    if [ x"$action" = x"install" ] ; then
266      exit_failure_syntax "icon-file argument missing"
267    else
268      exit_failure_syntax "icon-name argument missing"
269    fi
270fi
271
272xdg_size_name=
273extension=
274
275if [ -z "$size" ] ; then
276    exit_failure_syntax "the icon size must be specified with --size"
277fi
278xdg_size_name="${size}x${size}"
279
280if [ x"$action" = x"install" ] ; then
281    case $icon_file in
282      *.xpm)
283        extension="xpm"
284        ;;
285      *.png)
286        extension="png"
287        ;;
288      *)
289        exit_failure_syntax "icon file to install must be a *.png or *.xpm file"
290        ;;
291    esac
292fi
293
294if [ -n "$icon_name" ] ; then
295    case $icon_name in
296      *.png)
297         exit_failure_syntax "icon name should not include an extension"
298         ;;
299      *.xpm)
300         exit_failure_syntax "icon name should not include an extension"
301         ;;
302    esac
303fi
304
305# Start KDE legacy workaround section
306need_kde_icon_path()
307{
308  local path
309  path=`readlink -f "$1" 2> /dev/null` # Normalize path
310  DEBUG 2 "need_kde_icon_path $path"
311  if [ -z "$path" ] ; then
312     DEBUG 2 "need_kde_icon_path RETURN 1 (not needed, no xdg icon dir)"
313     return 1; # Not needed
314  fi
315
316  # if kde-config not found... return 0
317  kde_icon_dirs=`kde${KDE_SESSION_VERSION}-config --path icon 2> /dev/null |sed 's/:/ /g'`
318  DEBUG 3 "kde_icon_dirs: $kde_icon_dirs"
319  if [ -z "$kde_icon_dirs" ] ; then
320     DEBUG 3 "no result from kde${KDE_SESSION_VERSION}-config --path icon"
321     DEBUG 2 "need_kde_icon_path RETURN 1 (not needed, no kde icon path)"
322     return 1; # Not needed
323  fi
324  needed=0 # Needed
325  for y in $kde_icon_dirs ; do
326    x=`readlink -f "$y"` # Normalize path
327    DEBUG 3 "Normalize $y --> $x"
328    if [ -n "$x" ] ; then
329      if [ "$x" = "$path" ] ; then
330        needed=1 # Not needed
331      fi
332      if [ -w "$x" ] ; then
333        kde_global_prefix="$x"
334        # Take last writable dir
335      fi
336    fi
337  done
338  DEBUG 2 "kde_global_prefix: $kde_global_prefix"
339  [ $needed -eq "1" ] && DEBUG 2 "need_kde_icon_path RETURN $needed (not needed)"
340  [ $needed -eq "0" ] && DEBUG 2 "need_kde_icon_path RETURN $needed (needed)"
341  return $needed
342}
343
344kde_dir=
345if [ x"$mode" = x"user" ] ; then
346    xdg_dir="$xdg_base_dir/$xdg_size_name/$context"
347    #KDE 3.x doesn't support XDG_DATA_HOME for icons
348    #Check if xdg_dir prefix is listed by kde-config --path icon
349    #If not, install additional symlink to kdedir
350    if need_kde_icon_path "$xdg_user_prefix" ; then
351        kde_user_icon_dir=`kde${KDE_SESSION_VERSION}-config --path icon | cut -d ':' -f 1`
352        kde_user_dir="$kde_user_icon_dir/$theme"
353        kde_dir="$kde_user_dir/$xdg_size_name/$context"
354    fi
355    #Gnome 2.8 supports ~/.icons but not XDG_DATA_HOME
356    if [ -n "$dot_icon_dir" ] ; then
357        if [ -L "$dot_icon_dir" ] ; then
358            # Don't do anything
359            dot_icon_dir=
360        elif [ ! -d "$dot_icon_dir/" ] ; then
361            # Symlink if it doesn't exist
362            eval 'ln -s ".local/share/icons" "$dot_icon_dir"'$xdg_redirect_output
363            dot_icon_dir=
364        else
365            dot_icon_dir="$dot_icon_dir/$theme/$xdg_size_name/$context"
366        fi
367    fi
368    my_umask=077
369else
370    xdg_dir="$xdg_base_dir/$xdg_size_name/$context"
371    #KDE 3.x doesn't support XDG_DATA_DIRS for icons
372    #Check if xdg_dir prefix is listed by kde-config --path icon
373    #If not, install additional symlink to kdedir
374    if need_kde_icon_path "$xdg_global_prefix" ; then
375        kde_global_dir="$kde_global_prefix/$theme"
376        kde_dir="$kde_global_dir/$xdg_size_name/$context"
377    fi
378    my_umask=022
379fi
380# End KDE legacy workaround section
381
382# Start GNOME legacy workaround section
383need_gnome_mime=
384[ $context = "mimetypes" ] && need_gnome_mime=true
385# End GNOME legacy workaround section
386
387[ -n "$icon_name" ] || icon_name=`basename "$icon_file" | sed 's/\.[a-z][a-z][a-z]$//'`
388
389if [ "$vendor" = "true" -a "$action" = "install" -a "$context" = "apps" ] ; then
390    check_vendor_prefix "$icon_name" "icon name"
391fi
392
393icon_icon_file=`echo "$icon_file" | sed 's/\.[a-z][a-z][a-z]$/.icon/'`
394icon_icon_name="$icon_name.icon"
395
396DEBUG 1 "$action icon in $xdg_dir"
397[ $action = "install" -a -f $icon_icon_file ] && DEBUG 1 "install $icon_icon_name meta file in $xdg_dir"
398[ -n "$kde_dir" ] && DEBUG 1 "$action symlink in $kde_dir (KDE 3.x support)"
399[ -n "$need_gnome_mime" ] && DEBUG 1 "$action gnome-mime-$icon_name symlink (GNOME 2.x support)"
400[  $action = "install" -a -n "$dot_icon_dir" ] && DEBUG 1 "$action ~/.icons symlink (GNOME 2.8 support)"
401
402case $action in
403    install)
404        save_umask=`umask`
405        umask $my_umask
406
407        for icon_dir in $xdg_dir $dot_icon_dir; do
408            mkdir -p $icon_dir
409            eval 'cp "$icon_file" "$icon_dir/$icon_name.$extension"'$xdg_redirect_output
410            if [ -f "$icon_icon_file" ] ; then
411                eval 'cp "$icon_icon_file" "$icon_dir/$icon_icon_name"'$xdg_redirect_output
412            fi
413            if [ -n "$need_gnome_mime" ] ; then
414                eval 'ln -s "$icon_name.$extension" "$icon_dir/gnome-mime-$icon_name.$extension"'$xdg_redirect_output
415            fi
416        done
417        if [ -n "$kde_dir" ] ; then
418            mkdir -p $kde_dir
419            eval 'ln -s "$xdg_dir/$icon_name.$extension" "$kde_dir/$icon_name.$extension"'$xdg_redirect_output
420        fi
421
422        umask $save_umask
423        ;;
424
425    uninstall)
426        for icon_dir in $xdg_dir $dot_icon_dir; do
427            rm -f "$icon_dir/$icon_name.xpm" "$icon_dir/$icon_name.png"
428            rm -f "$icon_dir/$icon_icon_name"
429            if [ -n "$need_gnome_mime" ] ; then
430                rm -f "$icon_dir/gnome-mime-$icon_name.xpm"
431                rm -f "$icon_dir/gnome-mime-$icon_name.png"
432            fi
433        done
434        if [ -n "$kde_dir" ] ; then
435            rm -f "$kde_dir/$icon_name.xpm" "$kde_dir/$icon_name.png"
436        fi
437
438        ;;
439esac
440
441if [ x"$update" = x"yes" ] ; then
442    update_icon_database "$xdg_base_dir"
443    if [ -n "$dot_icon_dir" ] ; then
444        if [ -d "$dot_icon_dir/" -a ! -L "$dot_icon_dir" ] ; then
445            update_icon_database $dot_base_dir
446        fi
447    fi
448fi
449
450exit_success
451