Even if the number of files that change for customer specific code is small, having not just one client but several, probably all with different requirements, I think shows that you will have to opt for one of two solutions.
1. Which I do not recommend. If you can self contain said set of files, than you can have a generic set of files (that go with the regular baseline) and a number of customer specific set of files, set up in a separate project/folder/module. Depending on what you want to build, you can extract the appropriate set of files. Then, you could keep all of them on the TRUNK and build up ampersand modules to extract the appropriate set of baseline+custom code. The problems you will have, in no particular order are:
1. The architecture of the product has to support this.
2. It has to be planned out to support this particular setup with a forward vision from a coding/architecture perspective such that you will be able to entertain a wide array of such customer related coding should things and requirements change in the future.
3. You would need to instruct developers (and/or have custom triggers) to propagate all changes to the baseline/generic bucket of code to all of the other customer setups you have, as you will not be able to use the CVS merge facility.
Use branches, even though the files you change represent a small fraction of the product. But at least, you will be able to merge and/or tell what has changed in a sane manner. The issue you will have here, is that you will need to 'merge up' work from the baseline, into the customer specific area, which is kind of unusual since normally, you want to merge the work done on the branch, down to the TRUNK in order to collect work done in isolation into the product. So here your choices are, either to maintain static branches for customer buckets and merge up work done in the baseline into those buckets/branches, or, re graft your branches to start off of new places on TRUNK, which probably you want to at least represent a major milestone or iteration of your generic product. Then, you would merge all work done on the initial branch, onto the subsequent branch (off of say, the 2nd iteration). This should not be too bad, just make sure you understand how to merge, how to mark the root of each branch in the TRUNK such that you could always reference it, meaning, first create a label off of TRUNK that has the name of the branch followed by _ROOT, then create the branch off of that label.
cvs rtag M1_ROOT myprod
cvs rtag -b -rM1_ROOT M1 myprod
cvs -q up -dP -jM1 myprod (or if you have several merge points cvs -q up -dP -jM1_MERGED_LAST -jM1 myprod).