.deb package conffiles problem - linux

I am distributing one of my applications using a .deb package, but have a problem relating to one of the files.
The distribution includes a database file which is constantly updated by the app, on a fresh install I want the installer to copy a new, empty db file onto the users system, but on an upgrade I want the installer to leave the existing copy in place (overwriting it would result in all the users data getting lost).
Currently I have included the file in the 'conffiles' file, so the installer always asks the user whether to overwrite the existing file or not, but this isn't the behaviour I want - overwriting the file is never the right thing to do and I'm concerned that a user may pick the wrong option during an upgrade and hose their data.
Is there any way to tell the installer that if the db file already exists just leave it alone and don't ask the user what to do?

Yes, use a preinst/postinst script. The usual method is to name the file in the package with a special name ending with dpkg-new, for instance /var/lib/myapp/mydb.data.dpkg-new. Then write a 'postinst' script to put in the DEBIAN directory of your package to check for the existence of the database, and rename or delete the dpkg-new file accordingly, something like:
#!/bin/bash
if [ -f /var/lib/myapp/mydb.data ]; then
rm /var/lib/myapp/mydb.data.dpkg-new
else
mv /var/lib/myapp/mydb.data.dpkg-new /var/lib/myapp/mydb.data
fi

Related

Want to create a specific script for my Raspberry Pi to watch directory and do some actions

I am a complete newbie in writing scripts, I have just started a few days ago, and was already able to create simple scripts to find files, move them, delete them, etc...
I have a Raspberry Pi 4 with Raspberry Pi OS installed on it.
Now I want to create a better script, using "inotify" to monitor a specific directory and performs some actions if some specific files are found. Aaaaaand, I am a bit lost.
Here is what I have found and tested :
MONITORDIR="/my_dir"
inotifywait -m -r -e create --format '%w%f' "${MONITORDIR}" | while read NEWFILE
do
...
With this, I can generate an action whenever any new file appeared in my folder.
What I want :
If a new file with specific name (not the complete name, but just a part of the name of the file) with a specific .pdf extension is detected in the directory,
Then, move this file in another directory
And send an email using postfix, including the name of this new file, without the complete path of the file
Any help with this will be good for me, since I am a beginner, I know have a lot to learn, and I am sure I will.
Thank you !

Inno Setup - How to replace UserName with string

first attempt at posting this question was with severe jet lag. This re-edit of the question I only have the associated sleep deprivation...
I want to know the best way to use the installer to capture path information and then remove any reference to the user profile.
My program is designed to run from a central network location. To reduce network traffic some files are copied to a local drive, eg. AppData\MyProg\
I use a file browse dialogue so the person installing can specify the location:
pg_LocalPaths := CreateInputDirPage(pg_CentralPaths.id,
'Confirm File Locations For User Settings', 'To improve user experience these locations should be off the network.',
'Default Locations are:', False, 'New Folder');
// Add file browswer item (with an empty caption)
pg_LocalPaths.Add('Supporting files will be copied here by the application:');
pg_LocalPaths.Add('User settings (for a single user) will be saved here:');
// Set initial value
pg_LocalPaths.Values[0] := GetPreviousData('pg_LocalPaths0', ExpandConstant('{userappdata}\{#pFolder}'));
pg_LocalPaths.Values[1] := GetPreviousData('pg_LocalPaths1', ExpandConstant('{userappdata}\{#pFolder}'));
During install the local drive location is specified and stored in a config file.
An issue that I failed to predict is that when the program is installed, the path in the config file is defined for a single user, namely the user performing the install. In practice any user should be able to run the program...
To get the correct path for any given user, my software looks for a string "{UserName}" and replaces it with: Environ(UserName)
MyPath = Replace(MyPath, "{UserName}", Environ(UserName))
So, for example, in the installer I need to replace:
C:\Users\My Name\My Program OR C:\Users\My Admin\My Program
with something like:
C:\Users\\{UserName}\My Program
I alreay have this working in My Program but I am not sure of the best way to get it working in Inno... My inital thought was to write the config file like this:
StringChangeEx(MyPath, "My Name", "{UserName}", True)
Would like some perspective on this, not sure how to get it working for all situations.
Cheers,
You're doing it the wrong way.
Don't store the complete path in the config file; merely store a value that indicates that the user wishes to store data in the usual per-user location. (Or don't store any value, since that should be the default anyway.)
Then in your application, on every run of your application, use the Shell API to fetch the current AppData path for the current user and append your app's unique subfolder to this.
Note that it is perfectly valid for the user's AppData path to not contain their username, and not even be on C:. Don't make assumptions; use the Shell API. That's what it's for.
(Exactly which one to use and how to call it varies depending on target OS and your programming language of choice, which you haven't specified.)

Adding files to sourcecontrol on linux using cleartool

I have a file that i want to add to sourcecontrol on linux using cleartool .
I've followed the IBM documentation for this, i've tried this:
cleartool mkelem testScript.sh
I got an error: Can't modify directory "." because it is not checked out.
I also would like to know how can i checkout/checkin files or directories and setting activities.
You need to checkout the parent folder first.
cd /path/to/file/
cleartool mkact newfile
cleartool checkout -c "add file" .
cleartool mkelem testScript.sh
cleartool checkin -nc
The cleartool mkact would work if you are in an UCM view.
It will create and set a new activity, which will record the files and folder you will modify.
Here, the new activity newFile will record the new version of the parent folder, as well as the version 0 and 1 of the file.
You should create separate questions for .. separate questions...
Going back to the original - the reason why it isn't working is, as VonC has pointed out, you haven't checked out the parent of the file. Remember, when you run "cleartool mkelem", you are about to modify the contents of the parent directory (. in this case) by adding a new "pointer" to the element you're now creating. As with everything else in clearcase, when you want to modify the contents of an element, you have to check it out first.
One of ClearCase's greatest strength (and hardest to wrap one's head around) is the concept of an "element", IMO. "Everything" behaves similarly with an element. Making any change to an "element" (file or directory) means you have to check it out first to make that change.
In the case of a file, that's easy to grasp - you're just editing lines in a file. For a directory, it's almost as easy - you can think of a directory as just a list of pointers to data blobs. We make the name of the blob something convenient we can remember (like foo.java or myapplication.cc or README.md). But we can also change the name of the pointer (even though it points to the same data blob) by renaming a file. We can remove the pointer to the blob without impacting the blob itself by using "rmname". That's essentially what "rmname" does.
In ClearCases' case, the mkelem command is a little bit special - it creates the initial datablob, and adds a pointer to that datablob in the current directory (kind of does 2 things at once).

autotools not removing certain folders and files

I'm using autotools to package my software and compile. The problem I'm having is that during the installation process, I'm creating a folder in /etc/myapp and in that folder I'm placing several files that I need. In addition, when my software is running, I'm generating files and storing them in that same location (/etc/myapp). When I execute "sudo make uninstall", all of the files that were initially installed by using "sudo make install" are removed from /etc/myapp. However, the files that are generated by the software and store in that same spot are not removed and now I have left over files.
Where in the Makefile.am files would I specify to remove the entire /etc/myapp folder during the uninstall process?
FYI, I'm using Ubuntu 12.
Thank you
D
In your Makefile.am, you can create a target named uninstall-hook which will delete your generated files:
uninstall-hook:
rm -f $(DESTDIR)$(datadir)/my_generated_file $(DESTDIR)$(datadir)/my_other_generated_file
Or even:
uninstall-hook:
rm -rf $(DESTDIR)$(datadir)
Your question involves more than just tooling; it involves policy. What type of files are you creating? If they can be lost over a reboot, they (probably) belong under /var/run/myapp. If they are data files, they probably belong in $(prefix)/share/myapp. I say "probably" because it depends on the platform, and the user. Most debian users will want such files in the locations I mention above, but they may have reasons for putting them elsewhere. The important point is that it is the user's choice, not yours. As the package maintainer, you don't get to choose /etc/myapp. You need to configure your package to make those choices available to the user. The typical way to do that is to use automake's _DATA primaries and the 'sysconfdir', 'sharedstatedir', 'localstatedir', and 'pkgdatadir' family of variables.

Qt Installer framework - Copying files to location other than install directory

I know that, whatever data is placed in package/component dir/data, will be copied to the install directory. What I mean is if I have a binary, readme, license.txt inside package/component dir/data/myapp, package/component dir/data/readme, package/component dir/data/license.txt and if I choose my target installation dir to be “/opt/myfirstapp”, then inisde /opt/myfirstapp, I will have 3 files copied, myapp, readme, license.txt.
Having said that, I also have a “/usr” directory with in package/component dir/data/, however this is not the standard “/usr” which will be inside root “/”, it is just a replica. Now inside my replica “/usr” I have some directory hierarchy and some files, like /usr/bin/myapp, /usr/lib/libmyapp.so, /usr/share/icons” and many more, infact a lot. Now I want the replica “/usr” content to be copied to “/usr” (the original usr inside root folder). I should also make sure that I just add new contents to “/usr” (root /usr), but delete any existing content.
Question is clear, some files inside my data directory will have to go to target install dir, but some selected ones (for ex: /usr) will have to be copied to other paths. How do I achieve this.
Currently we have the same problem in my company: we need 2 target directories, one for the exe and one for the libraries (well, it's a bit more complex but in few words...).
After having spoken with Qt support and got the answer that it's actually not possible ("It is possible only after extracting. After extraction, you can use copy or move operation, unfortunately there is currently no other way.") I decided to use the AdminTargetDir as the second target directory. This because there's no other way to pass dynamic variables to the IFW. So after installation I call a "finalizeInstall_patch.bat" file passing the TargetDir and AdminTargetDir and this will move the libraries directory from TargetDir to AdminTargetDir. Why a .bat patch file ? because it's actually not possible to move a directory using the methods provided by the IFW. Qt support just opened a suggestion-ticket for our problem: https://bugreports.qt-project.org/browse/QTIFW-595
I hope that this answer will help others having same similar problems.
NOTE: There is a way to move a directory (on Windows), calling addOperation("Execute", "cmd /C move source dest...") but this brings to other problems out of topic here.
This worked for us (Qt Installer, macOS):
var args = ["cp", "-R", "#TargetDir#/MyApp.app", "/Applications"];
component.addOperation("Execute", args);

Resources